我读了几篇 answers昨天,关于使用static_assert(false, "Some message")
内else
if constexpr
的条款.我知道根据标准,它被认为是格式错误的(即使某些编译器,包括 MSVC2017 会接受它)。 Qt 也会将此标记为错误。
我的问题是,下面的代码是否符合标准? (我倾向于这么认为,但我想确认一下。)
template <typename TypeOfValue>
static void PushValue(duk_context* ctx, TypeOfValue value) {
// Push value onto duktape stack
if constexpr (std::is_same<TypeOfValue, int>::value) {
// Push int
duk_push_int(ctx, value);
} else if constexpr (std::is_same<TypeOfValue, uint32_t>::value) {
// Push uint
duk_push_uint(ctx, value);
} else {
// Unsupported type
static_assert(bool_value<false, TypeOfValue>(), "Unsupported type");
}
}
template <bool value, typename T>
static constexpr bool bool_value() {return value;}
编辑 :
从我得到的评论看来, bool_value 应该像这样定义:
template<bool value, typename T>
struct bool_value {
static constexpr bool value = value;
};
使用模式
// Unsupported type
static_assert(bool_value<false, TypeOfValue>::value, "Unsupported type");
然后它是格式良好的,只是因为 bool_value 可能被特化为一个版本,该版本为表达式
bool_value<false, TypeOfValue>::value
返回 true .
最佳答案
您的两次尝试(使用函数和使用结构)都按原样格式良好。
other answer提及 [temp.res]/8
,但我不同意它是如何解释的。
The validity of a template may be checked prior to any instantiation. ... The program is ill-formed, no diagnostic required, if:
— no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the template is not instantiated, or ...
你写的函数和结构体都可以特化为
true
.我相信仅仅有特化的可能性就足够了,你实际上不需要添加一个虚拟的 true
特化使代码格式良好。根据我的理解(我希望也是根据常识),这部分标准的重点是允许编译器检查模板的有效性和
if constexpr
尽早分支(当它们第一次被看到时),并拒绝那些不可能被实例化的分支。模板中的每个分支都可能被实例化,因为
bool_value()
以后可以专攻。我怀疑一个理智的编译器会因为 bool_value()
而拒绝你的代码还没有被特化。
关于c++ - 如果 constexpr 格式正确,这是在内部使用 static_assert 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62359172/