static_assert失败检查模板化对象指针

时间:2015-05-23 17:59:38

标签: c++ templates c++11 assertions static-assert

template <size_t N>
class Foo
{
    static_assert(N > 0, "WRONG");
    //void Something() = 0; //my original implementation
};

int main() {

    Foo<0> *p2 = nullptr;   //no error
    Foo<0> p;   //gives an error

    return 0;
}

我已分别测试了两条线。初始化p2时不调用static_assert但是它被调用并确实在p上失败。这是有意的吗? (我已经在gcc,clang和VC上试过了)

有哪些解决方法?由于我使用抽象模板化类,如果断言仅在实例化非指针对象时执行,那将是一场噩梦。我可以使用工厂,但这不是一个恰当的解决方案。

1 个答案:

答案 0 :(得分:6)

你肯定从§14.7.1/ 1中看到了这句话:

  

除非已明确表示类模板特化   实例化(14.7.2)或明确专门化(14.7.3),类   模板特化是隐式实例化的时的   在需要a的上下文中引用特化   完全定义的对象类型或类的完整性   type会影响程序的语义。

指针类型不要求它们的指针成为完整类型(例如void*就是一个例子)。因此第一行不会实例化专门化,但第二行需要实例化,因此断言仅在该行上触发。

这也可以通过下面的三个段落来解决:

  

[示例

template<class T> struct Z {
  void f();
  void g();
};

void h() {
  Z<int> a;      // instantiation of class Z<int> required
  Z<double>* q;  // instantiation of class Z<double> not required
  //[…]
}
     

此示例中的任何内容都不需要隐式实例化类Z<double> [...]。 - 结束示例]