c++ - 如果 constexpr 格式正确,这是在内部使用 static_assert 吗?

标签 c++ language-lawyer constexpr static-assert if-constexpr

我读了几篇 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/

相关文章:

c++ - 在opencv c++中使用过滤器卷积图像时出错

c++ - vector 堆排序

c - 在 C 中,如何确保内存加载只执行一次?

c++ - 为什么不能在常量表达式中使用 reinterpret_cast?

c++ - 为什么 Visual Studio 不允许我在 enable_if 中使用模板化的 constexpr 函数?

c++ - 如何取消 CallWndProc 钩子(Hook)中的消息

c++ - Boost::Thread 函数导致嵌入式 ARM 上的段错误

c++ - C++ 语言定义对 static 关键字的范围有什么看法?

c++ - 我可以编写一个返回函数的函数类型吗?

c++ - 为什么即使使用 constexpr 索引,编译器也允许越界访问数组?