c++ - 添加 'constexpr' 可以改变行为吗?

标签 c++ c++11 constexpr

给定两个程序,其中源代码的唯一区别是存在或不存在一个 constexpr,程序的含义是否可能改变?

换句话说,如果有一个编译器选项要求编译器在可能的情况下非常努力地推断 constexpr,它会破坏现有的标准代码和/或以不好的方式改变其含义吗?

想象一下原始开发人员忘记在可能的地方包含 constexpr 的代码库,可能是在 C++11 之前编写的代码。如果编译器能够推断出 constexpr 来帮助您继续工作,那就太好了。当然,也许它也应该在每次执行此推断时发出警告,鼓励您稍后显式添加 constexpr。但它仍然很有用。我担心它可能会破坏东西?

到目前为止,我唯一能想到的是 constexpr 函数是隐式 inline 并且可能存在添加 inline 的情况以不好的方式改变事情;例如,如果您违反了单一定义规则。

最佳答案

有一个简单的技巧:

template<int n>struct i{};
int foo(int){return 0;}
constexpr int foo(char){return 'a';}

template<class T=int, T x=1,i<foo(x)>* =nullptr>
bool bar(){return true;}
template<class T=int, T x=1,class...Ts>
bool bar(Ts...){return false;}

如果 int foo(int)是 constexpr,bar 的不同重载默认选择。

运行不同的代码,任何行为都可能发生变化。

live example (只需更改注释掉的 #define X)。


示例设计:

char重载可防止上述代码格式错误,无需诊断,因为所有模板都必须具有有效的特化。 foo<char>供应。实际上,它的存在不是必需的:ADL 可以找到 foo远在some_type* 上重载,然后通过 some_type*作为 T .这意味着没有编译单元可以证明代码格式错误。

Ts...使 bar重载不太喜欢。因此,如果第一个匹配,则没有歧义。只有当第一个重载失败(由于 foo(x) 不是 constexpr 引起的 SFINAE)时,才会调用第二个重载(或者,如果有人向它传递了参数)。

关于c++ - 添加 'constexpr' 可以改变行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32397105/

相关文章:

c++ - 终止模板搜索

c++ - 如何将 CINT 嵌入到 Windows 上的 C++ 应用程序中?

c++ - SDL GL 程序立即终止

c++ - header 正确,但找不到标识符

c++ - 构造函数中的模板冲突

c++ - 涉及接口(interface)中转发引用的重载

c++ - `const auto` 有什么意义吗?

c++ - MSVC 2017 违反单个翻译单元内的静态初始化顺序

c++ - 如何在编译时检查两种类型是否相同(如果它与 Boost strong typedef 一起使用则加分)

c++ - 类定义应该放在全局还是局部范围内?