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

static_assert fails check on templated object pointer

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;
}

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

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

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

Unless a class template specialization has been explicitly instantiated (14.7.2) or explicitly specialized (14.7.3), the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type or when the completeness of the class type affects the semantics of the program.

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

下面三段的示例也解决了这个问题:

[ Example:

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
  //[…]
}

Nothing in this example requires class Z<double> […] to be implicitly instantiated. — end example ]