一个判断C++模版类是否特化的方法。

假如我们有下面这一个C++模版类:

template<typename T>
class Foo {
  ...

  void bar() {
    ...
  }
}

模板类Foo有个方法bar()。假设有一个要求,对于不同类型的模版参数T,都要实现各自的bar(),而不是使用模板里面定义的bar()的版本。假设T是一个std::string的话,那么模板Foo针对std::string的特化,必须提供一个自己的bar()的实现,如下所示:

template<>
void Foo<std::string>::bar() {
  ...
}

在默认情况下,如果不提供特化版本的bar(),那么模板类Foo的特化就会使用Foo提供默认的bar(),如果我们不希望看到这种情况,应该怎么做呢?一个办法是根据sizeof(T)来判断:

template<typename T>
class Foo {
  void bar() {
    static_assert(sizeof(T) == 0, "should specialize this method");
  }
}

如上所示,模板类Foo的bar()增加了一条语句:

    static_assert(sizeof(T) == 0, "should specialize this method");

这条语句的奥妙之处在于:

  • static_assert是一个编译时期的断言,如果sizeof(T) == 0不满足,那么就会报出错误"should specialize this method",从而组织编译继续进行。
  • sizeof(T)也是一个编译时期的操作,如果模板没有经过特化,也就是说typename T未知,那么sizeof(T)的结果就是0,这样就触发了static_assert从而让编译器报告错误信息。

其他参考