在发现Boost预处理器的功能后,我发现自己在想:C99预处理器Turing是否完整?
如果没有,缺少什么不符合资格?
我刚刚注意到新标准的定义min(a,b)和max(a,b) 不 定义constexpr.
例25.4.7,[alg.min.max]:
template<class T> const T& min(const T& a, const T& b);
template<class T> T min(initializer_list<T> t);
Run Code Online (Sandbox Code Playgroud)
这不是很可惜吗?我本来想写的
char data[ max(sizeof(A),sizeof(B)) ];
Run Code Online (Sandbox Code Playgroud)
代替
char data[ sizeof(A) > sizeof(B) ? sizeof(A) : sizeof(B) ];
char data[ MAX(sizeof(A),sizeof(B)) ]; // using a macro
Run Code Online (Sandbox Code Playgroud)
那些不可能的constexpr原因是什么?
据我了解,constexpr与模板元编程不同,图灵不是完整的,所以我相信这些不一样.那么问题是constexpr模板元编程在多大程度上已经过时了?
#include <exception>
constexpr bool foo(bool x)
{
return x ? true : throw std::exception();
}
int main()
{
// 1) must never be compiled
// static_assert(foo(false), "");
// 2) must always be compiled?
const bool x = foo(false);
// 3) must never compile?
constexpr bool y = foo(false);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我确信(1)必须导致编译错误.我很确定(2)在编译时不能被拒绝,尽管它会在运行时失败.
有趣的案例是constexpr变量(3).在这个简单的例子中,gcc和clang实际上会计算表达式,因此会拒绝该程序.(错误消息:y不是常量表达式).
每个C++ 11编译器都被迫拒绝该程序吗?如果foo(false)被更复杂的表达式替换怎么办?
我很惊讶地发现constexpr没有图灵完整,虽然它将在规范发生变化之后: 基于constexpr的计算Turing是否完整?
也许这与我的问题有关.据我所知,允许编译器推迟在本例中对constexpr(3)的实际评估,直到运行时.但是如果constexpr是turing-complete,我发现很难相信编译器可以决定是否所有constexpr都会抛出异常(这意味着constexpr无效).