SFINAE может добавить шаблон проблемы - PullRequest
4 голосов
/ 15 января 2010

Я пытаюсь написать шаблон 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 (...) и будет использовать его вместо этого (и не будет жаловаться на то, что не разбирает .

Очевидно, что я что-то упускаю, я просто не знаю, что это такое.

1 Ответ

4 голосов
/ 15 января 2010

Мне кажется, что вы столкнулись с проблемой, которая обсуждалась в Core Issue 339 , а также N2634 . Суть в том, что вы немного продвинулись дальше того, что в настоящее время может обрабатывать любой компилятор, даже если то, что вы делаете, разрешено стандартом. C ++ 0x добавит больше подробностей о том, что будет и не приведет к сбою SFINAE по сравнению с серьезной ошибкой. См. N3000 , §14.9.2, если вы хотите получить подробности.

...