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 ]
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 ]