2015-03-20 3 views
0

У меня есть код, который я хочу, чтобы TestEnableIf с различной специализацией имел другую функцию печати, но это не сработало, как было запланировано, с ошибкой, как показано ниже.C++ template sfinae error

struct myStruct; 
struct notMyStruct; 

template<typename T> struct TestEnableIf 
{ 
     template<typename boost::enable_if< boost::is_same<myStruct, T>, int >::type = 0> void print() 
     { 
      std::cout << "this is my struct" << std::endl; 
     } 

     template<typename boost::enable_if< boost::is_same<notMyStruct, T>, int>::type=0> void print() 
     { 
      std::cout << "This is not my struct" << std::endl; 
     } 


}; 

static void testIsSame() 
{ 

    TestEnableIf<myStruct> testEnable; 
    testEnable.print(); 
    TestEnableIf<notMyStruct> testNotEnable; 
    testNotEnable.print(); 
} 

../src/testBoostGeneric.h:39:90: error: no type named ‘type’ in ‘struct boost::enable_if, int>’ template, int>::type=0> void print() ^../src/testBoostGeneric.h: In instantiation of ‘struct TestEnableIf’: ../src/testBoostGeneric.h:53:29:
required from here ../src/testBoostGeneric.h:34:90: error: no type named ‘type’ in ‘struct boost::enable_if, int>’ template, int >::type = 0> void print()

То, что я не понимаю, должен SFINAE означать отказ специализации не является ошибкой, то почему компилятор должен жаловаться на провал?

ответ

3

SFINAE (S-подстановка), а не «специализация», кстати) для функций-членов не работает таким образом с параметрами типа класса. Простой способ обойти это использовать другой параметр шаблона:

template< 
    typename TCopy = T 
    typename boost::enable_if< boost::is_same<myStruct, TCopy>, int >::type = 0 
> void print() 
{ 
    std::cout << "this is my struct" << std::endl; 
} 

Я вытащил это из STL's CppCon talk. TL; DW: при использовании параметра типа T класса компилятор знает, что это за тип при создании экземпляра шаблона класса и будет проверять для члена type в этот момент времени. С дополнительным параметром типа TCopy, являющимся локальным для функции, компилятор не может точно знать, пока функция не будет создана, и в этот момент SFINAE может перейти, чтобы повлиять на настройку перегрузки для вызова.

+0

Что вы подразумеваете под параметрами типа класса? – 0x499602D2

+0

@ 0x499602D2. Терминология может быть не лучшей, но я имел в виду параметры шаблона 'TestEnableIf'. – chris

+0

Большое спасибо. Очень краткий ответ ... – Michael