C++ 静态断言无法检查模板化对象指针 模板 福班 { 静态_断言(N>0,“错误”); //void Something()=0;//我的原始实现 }; int main(){ Foo*p2=nullptr;//无错误 Foo p;//给出一个错误 返回0; }

C++ 静态断言无法检查模板化对象指针 模板 福班 { 静态_断言(N>0,“错误”); //void Something()=0;//我的原始实现 }; int main(){ Foo*p2=nullptr;//无错误 Foo p;//给出一个错误 返回0; },c++,templates,c++11,assertions,static-assert,C++,Templates,C++11,Assertions,Static Assert,我已经分别测试了这两条线。初始化p2时不调用static_assert,但是调用了它,并且在p上确实失败了。这是有意的吗?(我在gcc、clang和VC上试过) 解决办法是什么?由于我使用的是抽象模板类,如果断言仅在实例化非指针对象时执行,那将是一场噩梦。我可以使用工厂,但这不是一个正确的解决方案。您肯定看到了§14.7.1/1中的这句话: 除非已明确指定类模板专用化 实例化(14.7.2)或显式专门化(14.7.3),类 当 专门化是在需要 完全定义的对象类型或类的完整性 类型会影响程序的语义

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


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

您肯定看到了§14.7.1/1中的这句话:

除非已明确指定类模板专用化 实例化(14.7.2)或显式专门化(14.7.3),类 当 专门化是在需要 完全定义的对象类型或类的完整性 类型会影响程序的语义。

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

下面三段的例子也说明了这一点:

[示例:

模板结构Z{
无效f();
void g();
};
void h(){
Z a;//需要实例化类Z
Z*q;//不需要实例化类Z
//[…]
}
本例中的任何内容都不要求隐式实例化类
Z
[…]


这并不能完全回答您的问题,因为有一个变通方法很有用,但除非类模板专门化已显式实例化或显式专门化,当在需要完全定义的对象类型的上下文中引用专门化时,或者当类类型的完整性影响程序的语义时,会隐式实例化类模板专门化。可以使用指向不完整类型的指针,所以,当您只创建一个指向该类型的指针时,不会触发实例化。那么有解决方法吗?要确保解析静态断言?@crezefire是的,请确保实例化了专门化。
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;
}
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
  //[…]
}