Question

I am writing a simple wrapper for an elementary type, and am trying to avoid having to write too many flavors of standard operators. I was hoping implicit type conversion would help, but it does not. Here's a stripped down example:

struct Int
{
    int _i;
    Int(int i=0) :_i{i} {}
    Int operator+ (const Int& rhs) {return _i+rhs._i;}
};

int main(int argc, char *argv[])
{
    (void)(Int(1) + 2); // Fine
    (void)(2 + Int(1)); // error: invalid operands to binary expression ('int' and 'Int')
}

I am using llvm. The first line of main compiles fine. The second causes an error. Now, what I'd hoped would happen in the second line is that 2 would be implicitly converted to Int(2), followed by a call to operator+. Why isn't that happening? Why is the implicit conversion happening in the first line?

Was it helpful?

Solution

It happens in the first line because the only operator+ available is operator+(Int&) (which has an implicit first parameter of Int for the this instance). The second line fails because the first parameter is an int and it has no clue that it needs to convert it before attempting the operation (it doesn't know it needs to use Int::operator+).

You can avoid that problem by making the operator a non-member friend function (http://ideone.com/YCf7wX)

struct Int
{
    int _i;
    Int(int i=0) :_i{i} {}
    friend Int operator+(const Int& lhs, const Int& rhs);
};

Int operator+(const Int& lhs, const Int& rhs)
{
    return lhs._i+rhs._i;
}

int main() 
{
    Int i;
    i + 5;
    5 + i;
    return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top