1

このコードは失敗し、エラー メッセージが表示されます (行番号がオフになっています)。これを修正するにはどうすればよいですか (同じ意図を維持します)。

g++ -o c_test c_test.cpp

c_test.cpp: 関数 'int main(int, char**)' 内:

c_test.cpp:28:18: エラー: 'wcalc(CWrapped<5>::u_type&)' の呼び出しに一致する関数がありません

c_test.cpp:28:18: 注: 候補は:

c_test.cpp:17:58: 注: テンプレート int wcalc(typename CWrapped::u_type)

ラップされた型は "calc" 関数と "wcalc" 関数の両方に渡されますが、2 つ目の関数は失敗します。型をラップできるようにしたいので、コンパイル時の定義を使用してさまざまな型を指定できますが、同じラップされた関数を使用できます

// Example template class
template <int T_B>
class m_int {
public:
  int x;
  m_int() { x = T_B; }
  int to_int() { return(x); }
};

// Desired Typedef wrap
template <int T_BITS> struct CWrapped {
  typedef m_int<T_BITS> u_type;
};


// This is ok, no wrapping
template <int T_BITS> int calc(m_int<T_BITS> x) {
  return(x.to_int());
}
// This fails when instantiated
template <int T> int wcalc(typename CWrapped<T>::u_type x) {
  return(x.to_int());
}


int main(int argc, char* argv[]) {
  CWrapped<5>::u_type s;

  int x = calc(s);
  int y = wcalc(s);
  return(0);
}
4

2 に答える 2

3

C++11 標準の段落 14.8.2.5/16 から

「非型テンプレート パラメーターを使用した関数テンプレートの宣言で、非型テンプレート パラメーターが関数パラメーター リストの部分式で使用されている場合、式は上記で指定された非推定コンテキストです。例:」

template <int i> class A { / ... / };
template <int i> void g(A<i+1>);
template <int i> void f(A<i>, A<i+1>);
void k() {
    A<1> a1;
    A<2> a2;
    g(a1); // error: deduction fails for expression i+1
    g<0>(a1); // OK
    f(a1, a2); // OK
}

「注: テンプレート パラメーターは、推定されないコンテキストでのみ使用される場合、テンプレート引数推定に参加しません。たとえば:」

template<int i, typename T> 
T deduce(typename A<T>::X x, // T is not deduced hereT t, // but T is deduced here
typename B<i>::Y y); // i is not deduced here
A<int> a;
B<77> b;
int x = deduce<77>(a.xm, 62, b.ym);
// T is deduced to be int, a.xm must be convertible to
// A<int>::X
// i is explicitly specified to be 77, b.ym must be convertible
// to B<77>::Y

上記の理由により、非型のテンプレート パラメータTは推測できません。明示的に指定する必要があります。

int main(int argc, char* argv[]) {
  CWrapped<5>::u_type s;

  int x = calc(s);
  int y = wcalc<5>(s); // Template argument 5 cannot be deduced!
  return(0);
}

この関連リンクも参照してください: C++、テンプレート引数を推測できません(@NateKohl 提供)

于 2013-01-08T22:27:57.550 に答える
0

あなたの問題は、それが依存コンテキストでCWrappedのマップでintあることです。u_type

型推論が機能するには、マップ from u_typetoが必要です。int

テンプレート型推定は単純なパターン マッチングであり、任意のテンプレート構成を反転しません。

CWrapped例として、次のように解決されるものを抽出する方法を次に示しますT

template<typename T>
struct GetWrapped;

template<int N>
struct GetWrapped< m_int<N> > {
  typedef CWrapped< N > type;
};

template <int T> int wcalc(T const& x) {
  typedef typename GetWrapped<T>::type CWrappedType; // assuming you need it for something
  return(x.to_int());
}

Tそして、オーバーロード解決でそのようなマッピングがあるものだけを受け入れる方法は次のとおりです。

#include <type_traits>
template <int T> auto wcalc(T const& x)->typename std::enable_if< sizeof(typename GetWrapped<T>::type), int>::type  {
  return(x.to_int());
}

これは、SFINAE と C++11 の機能を使用して、それGetWrapped<T>が有効な構造であることを確認します。

さて、これはおそらく XY の質問です。あなたが X に尋ねたように、あなたは本当に Y を知る必要がありました。上記のいずれかが役立つことを願っています。

于 2013-01-09T14:31:58.600 に答える