是否有方法将所有赋值运算符(+=、*=等)转发为隐式使用重写的直接赋值运算符(=)
Is there a way to forward all assignment operators (+=, *=, etc.) to implicitly use an overridden direct assignment operator (=)?
我知道"转发"在C++11中是一个无关的概念(就像在"完美转发"中一样),但它是我描述这个问题时想到的第一个词。
我正在重写包装类Proxy
,中的operator=
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.
有没有一个技巧可以"转发"所有赋值运算符(+=
、-=
、*=
、/=
、%=
、>>=
、<<=
、|=
、&=
、^=
),这样我就不必定义它们了?也就是说,一种制作的方法
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';
}
另一种不应忽视的方法是宏。。。。
有CRTP。
template<class D>
struct plus_equals {
template<class Rhs>
D& operator+=(Rhs&& rhs){
D*self=static_cast<D*>(this);
self->_data = (*self)+std::forward<Rhs>(rhs);
self->_state= State::SET;
return *self;
}
};
然后从CCD_ 19公开继承您的类CCD_。
当然,您需要为每个运算符编写样板文件,因此它对一种类型没有多大帮助。
相关文章:
- 重载Singly Linked List中的赋值运算符
- 使用赋值运算符重载从类中返回jobject
- 标准库类型的赋值运算符的引用限定符
- 复制构造函数、赋值运算符C++
- 标准::变体的赋值运算符
- 移动赋值运算符;尝试引用已删除的函数.我该如何解决这个问题?
- 基类和派生类的多态赋值运算符
- 为用户定义的类正确调用复制构造函数/赋值运算符
- CRTP 中的复制赋值运算符 - gcc vs clang 和 msvc
- 为什么初始化时没有调用重载赋值运算符?
- 赋值运算符重载和自赋值
- C++矢量复制构造函数和赋值运算符是否也复制保留空间?
- Qt PL/SQL - 赋值运算符 - 字符串缓冲区太小
- 对 r 值使用移动赋值运算符时的异常
- 由于没有使用赋值运算符,映射的值是如何初始化的?
- 默认赋值运算符如何在实际 STL 中实现
- 使用赋值运算符复制 std::vector
- C++ 通过自定义赋值运算符隐式转换函数参数
- C++重写赋值运算符
- 是否有方法将所有赋值运算符(+=、*=等)转发为隐式使用重写的直接赋值运算符(=)