在分配运算符中强制使用隐式强制转换

时间:2020-07-02 06:34:50

标签: c++ operator-overloading

在下面的代码中,有什么方法可以强制使用隐式强制转换为布尔值(在b3 = b2中)而不是在不使用强制转换运算符的情况下生成副本赋值运算符的编译器?不幸的是,在显式删除副本后,代码无法建立。缺少显式强制转换对我的框架很重要。

class Base
{
public :

   Base& operator=(const Base&) = delete;
   virtual Base& operator=(bool state) { state_ = state; }
   virtual operator bool() const { return state_; }
   virtual bool operator!() const { return !state_; }

protected :
   bool state_;
};

int main(void)
{
   Base b1, b2, b3;
   b1 = true;
   b2 = !b1;
   b3 = b2;

   return 0;
}

更新: 错误是

test.cpp: In function ‘int main()’:
test.cpp:20:9: error: use of deleted function ‘Base& Base::operator=(const Base&)’
    b3 = b2;
         ^~
test.cpp:6:10: note: declared here
    Base& operator=(const Base&) = delete;
          ^~~~~~~~

UPDATE2 : 正如@ serge-ballesta所说,基本分配运算符就足够了

#include <iostream>

class Base
{
public :

   virtual Base& operator=(const Base &rhs) { std::cout << "BASE = BASE" << std::endl; return *this = static_cast<bool>(rhs); };
   virtual Base& operator=(bool state) { std::cout << "BASE = bool" << std::endl;  state_ = state; return *this; }
   virtual operator bool() const { return state_; }
   virtual bool operator!() const { return !state_; }

protected :
   bool state_;
};

class Derived :
   public Base
{
public :
   virtual Base& operator=(bool state) { std::cout << "DERIVED = bool" << std::endl; state_ = state; /* And something more */ return *this; }
};

int main(void)
{
   Base b1, b2, b3;
   b1 = true;
   b2 = !b1;
   b3 = b2;

   Derived d1, d2, d3, d4;
   d1 = true;
   d2 = !d1;
   d3 = d2;
   d4 = b3;

   return 0;
}

输出为:

BASE = bool      # b1 = true;
BASE = bool      # b2 = !b1;

BASE = BASE      # b3 = b2;
BASE = bool      # ditto

DERIVED = bool   # d1 = true;
DERIVED = bool   # d2 = !d1;

BASE = BASE      # d3 = d2;
DERIVED = bool   # ditto

DERIVED = bool   # d4 = b3;

有趣的是,在最后一种情况下,隐式强制转换已按照我的意愿进行。

1 个答案:

答案 0 :(得分:1)

显式删除assign运算符意味着您希望该类不可复制。在这里,您只希望副本分配使用bool转换:

Base& operator=(const Base& other) {
    *this = static_cast<bool>(other);
    return *this;
}

不幸的是,您将不得不在派生类中重写赋值运算符,以强制使用此运算符:

class Derived: public Base {
public:
    Derived& operator=(Derived& other) {
        Base::operator = (other);
        return *this;
    }   
    ...
};