samedi 3 mars 2018

error C2678: binary '+': no operator found which takes a left-hand operand of type 'volatile A' (or there is no acceptable conversion)

I've programmed in C++ before, but it's been several years. I'm new to C++11 and I'm having trouble with the following.

My class is more complicated than just storing "twice the value given in the constructor", but for the sake of simplicity this example just multiplies the constructor input by 2. The class must implicitly convert to & from an int, thus the operator int(), operator=(const int), and constructor that takes an int.

Everything works fine unless an instance of my class is defined as volatile. When I subsequently try to do operations with the volatile instance, Visual Studio complains:

#include <iostream

class A
{
private:
   int _i;
public:
   A() = default;
   constexpr A(const int i) : _i(i*2) {}
   constexpr operator int() const { return _i/2; }
   A& operator=(const int i) { _i = i*2; }
};

//A va; // <---- this works (though I need it to be 'volatile')
volatile A va; // <--- this gives error C2678: binary '+': no operator found which takes a left-hand operand of type 'volatile A' (or there is no acceptable conversion)

int main()
{
   int j;
   j = va + 12; // <--- Here's where the error occurs
   std::cout << "j = " << j << std::endl;
}

Seeing that the error suggests that there's "no acceptable conversion", I tried adding to the class a copy constructor that takes a volatile other, but that didn't fix the problem:

   constexpr A(volatile const A& other) : _i(other._i) {}

I can "fix" it by casting away the volatile...

   j = (A)va + 12;

...but that solution doesn't work for me because my class is actually part of a simulator environment that's trying to simulate embedded hardware and run the embedded code within the simulation environment. My class has to act as a stand-in for hardware registers, and I can't (or don't want to) cast away volatile in the statement j = va + 12; because that line is part of the embedded firmware itself. Is there some conversion operator or method I can add to my class A to make the statement j = va + 12; work without modification?

Aucun commentaire:

Enregistrer un commentaire