Nabuchodonozor
Nabuchodonozor

Reputation: 736

Force using implicit cast in assign opertor

In following code is there any way to force on compiler using implicit cast to bool (in b3 = b2 assignment) instead of generating copy assignment operator without using cast operator? Unfortunately after explicit deleting copy assignment code does not build. Lack of explicit casting is important for my framework.

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;
}

UPDATE: Error is

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: As @serge-ballesta said base assignment operator is sufficient

#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;
}

And the output is:

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;

Interestingly in last case the implicit casting was done as I wanted to.

Upvotes: 0

Views: 138

Answers (1)

Serge Ballesta
Serge Ballesta

Reputation: 148900

Explicitely deleting the assign operator means that you want the class to be non copyable. Here, you just want the copy assignment to use a bool conversion:

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

Unfortunately, you will have to override the assignment operator in derived classes to force the use of this one:

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

Upvotes: 1

Related Questions