P0292R1 constexpr如果已包含在内,正在进行 C++ 17.它似乎很有用(并且可以取代SFINAE的使用),但关于static_assert形成不良的评论,假分支中不需要诊断会让我害怕:
Disarming static_assert declarations in the non-taken branch of a
constexpr if is not proposed.
void f() {
if constexpr (false)
static_assert(false); // ill-formed
}
template<class T>
void g() {
if constexpr (false)
static_assert(false); // ill-formed; no
// diagnostic required for template definition
}
Run Code Online (Sandbox Code Playgroud)
我认为它是完全禁止static_assert在constexpr内部使用if(至少是假/非分支,但实际上这意味着它不是一个安全或有用的事情).
这是如何从标准文本中产生的?我发现static_assert在提案中没有提到措辞,并且C++ 14 constexpr函数允许static_assert(cppreference的详细信息:constexpr).
是否隐藏在这个新句子中(6.4.1之后)?:
当constexpr if语句出现在模板化实体中时,在封闭模板或通用lambda的实例化期间,不会实例化丢弃的语句.
从那以后,我认为它也是禁止的,不需要诊断,调用调用图中某个地方可能调用的其他constexpr(模板)函数static_assert.
底线:
如果我的理解是正确的,那么对于constexpr …
template <int answer> struct Hitchhiker {
static_assert(sizeof(answer) != sizeof(answer), "Invalid answer");
};
template <> struct Hitchhiker<42> {};
Run Code Online (Sandbox Code Playgroud)
在尝试禁用常规模板实例化的同时,static_assert我发现clang即使模板未实例化,上面的代码也会生成断言错误,而gcc只有在Hitchhiker使用除了以外的参数进行实例化时才生成断言错误42.
摆弄我发现这个断言:
template <int answer> struct Hitchhiker {
static_assert(sizeof(int[answer]) != sizeof(int[answer]), "Invalid answer");
};
template <> struct Hitchhiker<42> {};
Run Code Online (Sandbox Code Playgroud)
两个编译器的行为相同:只有在实例化通用模板时,断言才会启动.
标准说什么,哪个编译器是对的?
g++ 4.9.2
clang++ 3.50
Run Code Online (Sandbox Code Playgroud)