模板特化是否需要模板<>语法?

Dre*_*ann 8 c++ syntax templates template-specialization

我有一个类似这样的访客类:

struct Visitor 
{
    template <typename T>
    void operator()(T t)
    {
        ...
    }

    void operator()(bool b)
    {
        ...
    }
};
Run Code Online (Sandbox Code Playgroud)

显然,operator()(bool b)旨在成为前面模板功能的专业化.

但是,它没有template<>我以前在其中看到的语法,将其声明为模板特化.但它确实编译.

这样安全吗?它是否正确?

Dav*_*eas 19

您的代码不是模板特化,而是非模板化的函数.那里有一些差异.非模板化运算符()将优先于模板化版本(对于完全匹配,但类型转换不会在那里发生),但您仍然可以强制调用模板化函数:

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
}
Run Code Online (Sandbox Code Playgroud)

在你的代码中没有太大的区别,但如果你的代码需要传递模板参数类型,它会变得更有趣:

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
}
Run Code Online (Sandbox Code Playgroud)

  • @詹姆士.编译器能够通过查看参数类型来推断显式特化的"T",因此在这种情况下,没有必要(除了作为样式首选项)显式指定模板参数.在这种情况下,实际上存在一个核心问题,即允许从返回类型中扣除,这通常是不可能的:http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#621 (3认同)

Luc*_*lle 5

你在这里有功能重载; 要获得模板专业化,您确实需要template <>语法.但是,您应该知道这两种方法,即使它们看起来相同,也略有不同,甚至编译器在选择正确的函数时也可能会丢失.列出所有可能的案例对于这个答案来说有点太长了,但你可能想要检查一下Herb Sutter GoTW#49.