3 回答
TA贡献1829条经验 获得超4个赞
如果由于不依赖于模板参数的构造而导致模板定义后的假想实例化格式不正确,则程序格式不正确;无需诊断。
N4296 [温度] / 8
这在定义了主模板(其中有一个static_assert)之后立即适用。因此,以后的专业化(for 42)尚不存在,因此无法考虑。
接下来的问题是,如果static_assert( sizeof(answer) != sizeof(answer), 依赖于answer。在语义上没有,在语法上没有,并且在标准方面:
在模板内部,某些构造的语义可能因一个实例而异。这样的构造取决于模板参数。
N4296 [温度深度] / 1
构造sizeof(answer) != sizeof(answer)从一个实例到另一个实例没有不同。因此,这种构造不依赖于模板参数。这意味着整个过程static_assert不取决于template参数。
因此,您的程序格式错误,不需要诊断。发出任意诊断(例如static_assert失败)是有效的编译器行为。缺少问题是有效的编译器行为。由标准格式未定义的,由错误格式编译的程序的行为:未定义的行为。允许鼻恶魔。
花哨的尝试(例如sizeof(int[answer])!=sizeof(int[answer])可能会喜欢当前的上帝编译器,但不会使您的程序格式更好。
您可能会遇到这样的情况,即编译器不太可能抓住您,但是不管编译器是否能够抓住您,它的格式仍然不正确。通常,C ++希望保留自身(及其编译器)的自由,以“早于实例化”来查找无效的模板代码。这意味着模板代码必须产生可能的合法代码。
您可能想要=delete带有附加消息的内容。
TA贡献1841条经验 获得超3个赞
两种编译器都是正确的。从[temp.res] / 8:
如果无法为模板生成有效的专业化名称,并且该模板未实例化,则该模板格式错误,无需诊断。
没有可以从主模板生成的有效专业化名称Hitchhiker,因此它格式不正确,不需要诊断。clang选择仍然发出诊断。
如果您只想允许42,则只需不定义常规模板:
template <int > struct Hitchhiker;
template <> struct Hitchhiker<42> {};
TA贡献1871条经验 获得超13个赞
我不同意您对[temp.dep] / 1的解释:我认为May 可以作为编译器的余地,以避免实际尝试构造一个实例或另一个实例中是否确实具有不同语义的问题,并且相反,让编译器决定是否有可能具有不同的语义(它提到模板参数),则将其视为“ depends”。我认为,这条路非常重要,因为表达式可以任意卷积,从而确定实例化是否可能是复杂的。
- 3 回答
- 0 关注
- 626 浏览
添加回答
举报