给定两个程序,其中源代码的唯一区别是存在或不存在一个 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/