4

2 つのクラスを一緒に追加できるかどうかを判断するために、SFINAE テンプレートを作成しようとしています。これは主に、特定の「現実世界」の理由ではなく、SFINAE がどのように機能するかをよりよく理解するためのものです。

だから私が思いついたのは

#include <assert.h>

struct Vec
{
  Vec operator+(Vec v );
};

template<typename T1, typename T2>
struct CanBeAdded
{
  struct One { char _[1]; };
  struct Two { char _[2]; };

  template<typename W>
  static W make();

  template<int i>
  struct force_int { typedef void* T; }; 

  static One test_sfinae( typename force_int< sizeof( make<T1>() + make<T2>() ) >::T );
  static Two test_sfinae( ... );

  enum { value = sizeof( test_sfinae( NULL ) )==1 };
};


int main()
{
  assert((CanBeAdded<int, int>::value));
  assert((CanBeAdded<int, char*>::value));
  assert((CanBeAdded<char*, int>::value));
  assert((CanBeAdded<Vec, Vec>::value));
  assert((CanBeAdded<char*, int*>::value));
}

これは、最後の行を除くすべてについてコンパイルされ、次のようになります。

finae_test.cpp: In instantiation of ‘CanBeAdded<char*, int*>’:
sfinae_test.cpp:76:   instantiated from here
sfinae_test.cpp:40: error: invalid operands of types ‘char*’ and ‘int*’ to binary ‘operator+’

したがって、このエラーは私が予想するようなものですが、コンパイラーが test_sfinae( ... ) 定義を見つけて代わりに使用することを期待します (そして、解析しないものについて不平を言うことはありません.

明らかに何かが欠けています。それが何であるかわかりません。

4

1 に答える 1

4

CoreIssue339およびN2634で説明されている問題に遭遇したように見えます。肝心なのは、あなたがしていることは標準で許可されているとしても、コンパイラが現在処理できるものを少し超えているということです。C ++ 0xは、SFINAEエラーとハードエラーの結果となるものとそうでないものについての詳細を追加します。厄介な詳細を知りたい場合は、 N3000、§14.9.2を参照してください。

于 2010-01-15T07:02:06.583 に答える