あなたのコードはテンプレートの特殊化ではなく、テンプレート化されていない関数です。そこにはいくつかの違いがあります。テンプレート化されていない operator() は、テンプレート化されたバージョンよりも優先されます (完全一致の場合、型変換は行われません) が、テンプレート化された関数を強制的に呼び出すことができます。
class Visitor
{
public: // corrected as pointed by stefanB, thanks
template <typename T>
void operator()( T data ) {
std::cout << "generic template" << std::endl;
}
void operator()( bool data ) {
std::cout << "regular member function" << std::endl;
}
};
template <> // Corrected: specialization is a new definition, not a declaration, thanks again stefanB
void Visitor::operator()( int data ) {
std::cout << "specialization" << std::endl;
}
int main()
{
Visitor v;
v( 5 ); // specialization
v( true ); // regular member function
v.operator()<bool>( true ); // generic template even if there is a non-templated overload
// operator() must be specified there (signature of the method) for the compiler to
// detect what part is a template. You cannot use <> right after a variable name
}
あなたのコードでは大きな違いはありませんが、コードがテンプレート パラメーターの型を渡す必要がある場合は、より面白くなります。
template <typename T>
T g() {
return T();
}
template <>
int g() {
return 0;
}
int g() {
return 1;
}
int main()
{
g<double>(); // return 0.0
g<int>(); // return 0
g(); // return 1 -- non-templated functions take precedence over templated ones
}