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上试过了)
有哪些解决方法?由于我使用抽象模板化类,如果断言仅在实例化非指针对象时执行,那将是一场噩梦。我可以使用工厂,但这不是一个恰当的解决方案。
答案 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>
[...]。 - 结束示例]