jeudi 2 août 2018

implicit conversion not performed on overloaded operator+'s arguments?

All codes are compiled on g++ 6.4.0 with -std=c++11 option. Consider the following:

#include<iostream>
using std::cout;
using std::endl;
struct Direction{
    int dx,dy;
};
struct Point{
    int x,y;
    Point operator+(const Direction& d){
        return {x+d.dx,y+d.dy}
    }
};
int g(const Direction& d){
    return d.dx+d.dy;
}
int f(const Point& p){
    return p.x+p.y;
}
int main(){
    cout << g({1,2}) << endl;
    cout << f({1,2}) << endl;
    Point A {1,3};
    cout << f(A+{1,1}) << endl; //line 25
}

The compiler complains,

25 | error: expected primary-expression before '{' token

When line 25 is removed, the program works well, outputting two 3s seperated by a '\n'. However, I am a bit puzzled.

As far as my knowledge extends, line 25 should work like this:

  1. The only Point::operator+ takes a const Direction& as its only argument. Because it can, {1,1} is implicitly converted to an object of type Direction, just like how f({1,2}) is evaluated as f(Point{1,2}). Though this object is temporary, this shouldn't matter, as the argument is const.
  2. int f(const Point& p) takes this temporary "Point {2,4}" as an argument and returns a 6.
  3. 6 is outputted, followed by an '\n'.

But this is not the case.

Do implicit conversions not work for overloaded operators? but we know this is not the case, because the below code certainly works properly, outputting a 98 in my system:

#include<iostream>
int main(){
    std::cout << 1 + 'a' << std::endl;
}

I also considered the possibility that two implicit conversions in one line is a no-no, but the below code compiles:

int main(){ //line 21: continued from the code at the top
    cout << g({1,2}) + f({1,2}) << endl;
}

My question is:

**1. Why does line 25 give errors

  1. and what should I additionally define so that I can preserve the expression in line 25?**

Thank you.

Aucun commentaire:

Enregistrer un commentaire