c++ - 有没有办法将所有赋值运算符(+=、*= 等)转发为隐式使用重写的直接赋值运算符 (=)?

标签 c++ templates c++11 operator-overloading wrapper

我知道“转发”在 C++11 中是一个不相关的概念(如“完美转发”),但这是我在描述问题时想到的第一个词。

我正在覆盖 operator=在包装类中 Proxy ,

template<typename T>
class Proxy
{
public:
    enum class State
    {
        NEVER_SET = 0,
        SET
    };
    operator const T& () const
    {
        if ( _state != State::SET )
        {
            throw std::domain_error{ "using unset data" };
        }
        return _data;
    }
    Proxy<T>& operator=(const T& val)
    {
        _data = val;
        _state = State::SET;
        return (*this);
    }
private:
    T _data;
    State _state = State::NEVER_SET;
};

但发现自己还需要添加:

    Proxy<T>& operator+=(const T& val)
    {
        _data = (*this) + val;
        _state = State::SET;
        return (*this);
    }
    Proxy<T>& operator-=(const T& val)
    {
        _data = (*this) - val;
        _state = State::SET;
        return (*this);
    }
    Proxy<T>& operator*=(const T& val)
    {
        _data = (*this) * val;
        _state = State::SET;
        return (*this);
    }
    Proxy<T>& operator/=(const T& val)
    {
        _data = (*this) / val;
        _state = State::SET;
        return (*this);
    }
    // ...and so on.

是否有“转发”所有赋值运算符的技巧( +=-=*=/=%=>>=<<=|= 、 |104 567915| , &= )这样我就不必定义它们?也就是说,一种方法使得

Proxy<double> x = 7;
Proxy<double> y = 43;
x += y;

自动“解开”到

Proxy<double> x = 7;
Proxy<double> y = 43;
x = x + y; // cast operator converts x and y to double, then direct assigns sum,
           // therefore no += needing definition in Proxy<T>

最佳答案

您可以使用 CRTP,但如果您的目标是在 Proxy 类中只包含显式 =,则需要提供对其他运算符已可用的类型的某些访问权限。换句话说,如果您定义了如何分配但没有定义如何添加,则不能说 a1 = a2 + a3。我在下面通过期望一个 get() 函数来解决这个问题,该函数公开一些可以操作的状态。明确定义例如更典型(并且可能更实用) += 然后根据它定义 +....

#include <iostream>

template <typename T>
struct Implied_Ops
{
    T operator+(const T& rhs) const
    {
        return rhs.get() + static_cast<const T*>(this)->get();
    }

    T& operator+=(const T& rhs)
    {
        return static_cast<T&>(*this) = operator+(rhs);
    }
};

struct X : Implied_Ops<X>
{
    X(int n) : n_(n) { }
    X& operator=(const X& rhs) { n_ = rhs.n_; return *this; }
    int get() const { return n_; }
    int n_;
};

int main()
{
    X x { 10 };
    X x2 = x + x;
    X x3 = x + x2;
    std::cout << x.n_ << ' ' << x2.n_ << ' ' << x3.n_ << '\n';
}

另一种不容忽视的方法是宏......

关于c++ - 有没有办法将所有赋值运算符(+=、*= 等)转发为隐式使用重写的直接赋值运算符 (=)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25635433/

相关文章:

c++ - 检测给定类型是否为 C++03 中的函数类型

c++ - Friend函数无法构造类的唯一指针

C++0x 元组没有迭代器,对吗?

android - QtCreator : how to see program output when deployed on Android

c++ - 无法理解C程序中Append()中的代码

java - 在 Eclipse 中设置 Velocity

c++ - 具有静态存储的变量地址模板

c++ - 为什么我需要 std 和字符串库才能在 C++ 中使用字符串

c++ - 如何设置 int64 的较低或较高值?

在用户插入的字符串的每个元音后插入一对字符的 C++ 代码