自然算术C ++总是返回1

时间:2018-06-03 23:53:39

标签: c++ types

我正在尝试用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!

1 个答案:

答案 0 :(得分:2)

S(const S& s)是一个复制构造函数,在某些情况下,允许编译器elide calls到复制构造函数。这是C ++ 14及更低版本中的可选优化,在C ++ 17中是必需的。您可以通过在此构造函数中放置一个print语句来验证是否发生了这种情况,该构造函数不会打印任何内容。

在这种情况下,它会使表达式S(S(O()))等同于S(O())

因此,这种做事方式在这里不起作用。您可以改为S一个函数,它可以返回一个整数(使其变得微不足道),或者如果您希望在此处保留类似于您的代码的某个对象。