Понятно, что этот баг закрыт в новой версии компилятора, но тем, кто ещё пользуется VC2010, может пригодиться "на заметку".
#include <iostream>
using namespace std;
typedef void (*FOO)();
typedef void (*BAR)(int,int,int);
template<FOO f> void go(int) { cout << "go<FOO> : "; f(); cout << endl; } // line 7
template<BAR b> void go(int) { cout << "go<BAR> : "; b(1,2,3); cout << endl; } // line 8
void foo() { cout << "foo"; }
void bar(int,int,int) { cout << "bar"; }
int main()
{
go<foo>(1); // line 15
go<bar>(1); // line 16
}
gcc даже 4.6 это умеет, VC2012 тоже умеет, а VC2010 пишет ошибки
xz.cpp(15) : error C2440: 'specialization' : cannot convert from 'void (__cdecl *)(void)' to 'const BAR'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
xz.cpp(15) : error C2973: 'go' : invalid template argument 'void (__cdecl *)(void)'
xz.cpp(8) : see declaration of 'go'
xz.cpp(15) : error C2668: 'go' : ambiguous call to overloaded function
xz.cpp(8): could be 'void go<void foo(void)>(int)'
xz.cpp(7): or 'void go<void foo(void)>(int)'
while trying to match the argument list '(int)'
xz.cpp(16) : error C2440: 'specialization' : cannot convert from 'void (__cdecl *)(int,int,int)' to 'const FOO'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
xz.cpp(16) : error C2973: 'go' : invalid template argument 'void (__cdecl *)(int,int,int)'
xz.cpp(7) : see declaration of 'go'
xz.cpp(16) : error C2668: 'go' : ambiguous call to overloaded function
xz.cpp(8): could be 'void go<void bar(int,int,int)>(int)'
xz.cpp(7): or 'void go<void bar(int,int,int)>(int)'
while trying to match the argument list '(int)'
то есть, несовместимость типов вместо SFINAE трактует как полноценную ошибку.
27.02.14 16:10: Перенесено модератором из 'C/C++. Прикладные вопросы' — Кодт