简体   繁体   English

带有 SFINAE 的 static_assert

[英]static_assert with SFINAE

The standard says in [temp.res]/8:该标准在 [temp.res]/8 中说:

No diagnostic shall be issued for a template definition for which a valid specialization can be generated.对于可以生成有效特化的模板定义,不应发出诊断。 If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required.如果无法为模板定义生成有效的特化,并且该模板未实例化,则模板定义格式错误,无需诊断。 ... [ Note: If a template is instantiated, errors will be diagnosed according to the other rules in this Standard. ... [注:如果模板被实例化,错误将根据本标准中的其他规则进行诊断。 Exactly when these errors are diagnosed is a quality of implementation issue.准确诊断这些错误的时间是实施质量问题。 — end note ] ——尾注]

My question is: Does the following count as a valid specialization that can be generated?我的问题是:以下是否算作可以生成的有效专业化?

#include <type_traits>

template <typename T, typename Enable = void>
class A;

template <typename T>
class A<T, typename std::enable_if<not std::is_same<T, int>::value>::type>
{
public:
    static_assert(std::is_same<T, int>::value, "should not be here!");
};

On the one hand, the static_assert essentially amounts to a static_assert(false, "should not be here");一方面, static_assert本质上相当于一个static_assert(false, "should not be here"); (we can't both not be an int and be an int at the same time), which isn't allowed. (我们不能既不是int又是int ),这是不允许的。 On the other hand, as far as SFINAE is concerned, the type, eg, A<double> is perfectly well formed and can be generated, but will immediately throw a static assertion failure.另一方面,就 SFINAE 而言,类型,例如, A<double>格式完美,可以生成,但会立即抛出 static 断言失败。 This currently works in GCC 8.3, but given the "ill-formed, no diagnostic required" part of the standards quote above, I want to make sure that it actually should work.这目前在 GCC 8.3 中有效,但鉴于上述标准引用的“格式错误,无需诊断”部分,我想确保它确实应该有效。 (Note: work here is defined to mean it throws a static assertion failed if I try to instantiate a A<double> and compiles silently if I don't) (注意:这里的工作被定义为如果我尝试实例化A<double>则它会抛出static assertion失败,如果我不这样做则静默编译)

No, it's not meant to work.不,它不适合工作。 That is not a valid C++ program.这不是一个有效的 C++ 程序。

Per the very paragraph you cite, the template definition of your partial specialization is ill-formed NDR.根据您引用的段落,您的部分专业化的模板定义是格式错误的 NDR。 There is no valid specialization that may be generated from it.没有可以从中生成的有效专业化。

The standard typically designates something as ill-formed NDR because checking it reliably in the general case would amount to contradicting Rice's theorem .该标准通常将某些东西指定为格式错误的 NDR,因为在一般情况下对其进行可靠检查将等于与赖斯定理相矛盾。 So compilers aren't obligated to try, but they may try some heuristic analysis or other.所以编译器没有义务尝试,但他们可能会尝试一些启发式分析或其他。

GCC and Clang often diagnose more as heuristics are added to them. GCC 和 Clang 通常诊断更多,因为它们添加了启发式。 I wouldn't try to claim "this is dependent" as a shield against that.我不会试图声称“这是依赖的”作为反对这一点的盾牌。 The code itself is invalid from the get-go.代码本身从一开始就无效。

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

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