简体   繁体   English

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

I've tested both the lines separately. 我已经分别测试了这两条线。 static_assert is not called when p2 is initialized but it is called and does indeed fail on p. p2初始化时不会调用static_assert,但会在p上调用static_assert并确实失败。 Is this intended? 这是故意的吗? (I've tried it on gcc, clang and VC) (我已经在gcc,clang和VC上尝试过)

What are the workarounds? 有哪些解决方法? Since I'm using abstract templated classes, it would be a nightmare if the assertion is only performed when a non-pointer object is instantiated. 由于我使用的是抽象模板类,因此仅在实例化非指针对象时执行断言将是一场噩梦。 I can use a factory but that isn't exactly a proper solution. 我可以使用工厂,但这并不是正确的解决方案。

You assuredly saw this quote from §14.7.1/1: 您可以肯定地从§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. 除非已经明确实例化了类模板专业化(14.7.2)或明确了专门化(14.7.3), 否则当在需要完全定义的对象类型的上下文中引用该专业化或完整性时,将隐式实例化该类模板专业化类的类型会影响程序的语义。

Pointer types do not require their pointee to be a complete type (eg void* is an example of this). 指针类型不需要其指针是完整的类型(例如void*是其示例)。 Thus the first line will not instantiate the specialization, but the second one needs to, hence the assertion fires only on that one. 因此,第一行不会实例化专门化,但是第二行需要实例化,因此断言仅在该那一行上触发。

This is also addressed by an example three paragraphs further down: 下面的三段示例也解决了这一问题:

[ 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. 此示例中的任何内容均不需要隐式实例化类Z<double> […]。 end example ] 结束示例 ]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM