我正在尝试用C ++实现自然数,这是我到目前为止的代码(O()是0(零)数,S(Nat)是后继函数)。
// Peano arithmetic C++
// Null element
struct O{
explicit operator const unsigned int() const { return 0; }
};
// Successor function
struct S {
unsigned int val;
explicit operator const unsigned int() const {
// Boundary check
std::cout << "Incremented once" << std::endl;
if (this->val < UINT_MAX) {
return this->val + 1;
}
// Don't wrap around, hit the ceiling and stay there
return this->val;
}
S(const unsigned int a) {
this->val = a;
}
// Constructor
S(const O& zero) {
this->val = 0;
}
S(const S& s) {
this->val = static_cast<const unsigned int>(s);
}
};
// Nat
using Nat = std::variant<O, S>;
int main() {
std::cout << static_cast<const unsigned int>(S(O())) << std::endl;
std::cout << static_cast<const unsigned int>(S(S(O()))) << std::endl;
return 0;
}
我的期望是static_cast给unsigned给我1,2。我得到的实际上是1,1!
答案 0 :(得分:2)
S(const S& s)
是一个复制构造函数,在某些情况下,允许编译器elide calls到复制构造函数。这是C ++ 14及更低版本中的可选优化,在C ++ 17中是必需的。您可以通过在此构造函数中放置一个print语句来验证是否发生了这种情况,该构造函数不会打印任何内容。
在这种情况下,它会使表达式S(S(O()))
等同于S(O())
。
因此,这种做事方式在这里不起作用。您可以改为S
一个函数,它可以返回一个整数(使其变得微不足道),或者如果您希望在此处保留类似于您的代码的某个对象。