我们知道C++ template metaprogramming is Turing complete,但preprocessor metaprogramming is not。
C ++ 11为我们提供了一种新形式的元编程:constexpr函数的计算。这种计算形式是图灵完备吗?我在想,因为在constexpr函数中允许使用递归和条件运算符(?:),但是我希望有更多专业知识的人来确认。
答案 0 :(得分:55)
tl; dr:constexpr
并不是图灵完备的,但该错误已在后来的标准草案中得到解决,并且已经铿锵作响实现修复。
constexpr
不是图灵完备的。草图证明:
constexpr
的每个f
函数a...
的结果(或非终止)仅由a...
<的值确定/ LI>
[basic.types]p10
可以是:
a...
可以接收的可能输入f
的集合是有限的,因此任何有限描述的constexpr
系统都是有限状态机,因此不是图灵完备然而,自从C ++ 11标准发布以来,情况已经发生了变化。
Johannes Schaub对std::max() and std::min() not constexpr的回答中描述的问题被报告给C ++标准化委员会作为核心问题1454.在2012年2月的WG21会议上,我们认为这是标准中的缺陷,并且选择了分辨率包括使用指定临时对象的指针或引用成员创建类类型值的功能。这允许由constexpr
函数累积和处理无限量的信息,并且足以使constexpr
评估图灵完成(假设实现支持递归到无界深度)。
为了演示实现核心问题1454的解决方案的编译器的constexpr
的图灵完整性,我为clang的测试套件编写了图灵机模拟器:
http://llvm.org/svn/llvm-project/cfe/trunk/test/SemaCXX/constexpr-turing.cpp
g ++和clang的中继版本实现了这个核心问题的解决方案,但是g ++的实现目前无法处理这个代码。
答案 1 :(得分:7)
看看这些。我编译了这些示例,它们在GCC 4.6中工作: Compile-time computations,Parsing strings at compile-time - Part I,Parsing strings at compile-time - Part II
答案 2 :(得分:1)
如果我们考虑到真实计算机的限制 - 例如有限内存和MAX_INT的有限值 - 那么,当然,constexpr(以及整个C ++)并不是图灵完备的。
但是如果我们将删除这个限制 - 例如,如果我们将int视为一个完全正则的正整数 - 那么是的,constexpr C ++的一部分将是Turing完成的。表达任何部分递归函数都很容易。
0,S(n)= n + 1和选择器I_n ^ m(x_1,...,x_n)= x_m,显然可以用constexpr表示叠加。
原始递归可以直接进行:
constexpr int h(int x1, ..., int xn, int y) {
return (xn == 0) ? f(x1, ..., xn) : g(x1, ..., xn, y-1, h(x1, ..., xn, y-1));
}
对于部分递归,我们需要一个简单的技巧:
constexpr int h(int x1, ... int xn, int y = 0) {
return (f(x1, ... xn, y) == 0) ? y : h(x1, ..., xn, y+1);
}
因此我们将任何部分递归函数作为constexpr。