Ambiguous call with overloaded r-value reference f

2019-03-04 12:32发布

问题:

I have a class with the following declarations:

class IcoSphere
{
[...]
private:
    int _addVertex(const glm::vec3 &p);
    int addVertex(glm::vec3 p);
    int addVertex(const glm::vec3 &&p);
[...]
};

Then, I'm calling 'addVertex' like so:

IcoSphere sphere;
double t = (1.0 +sqrt(5.0)) /2.0;
sphere.addVertex(glm::vec3(-1,t,0));

The argument for 'addVertex' is obviously not a reference, and yet the g++-compiler throws the following error:

./network/icosphere.cpp: In static member function ‘static void IcoSphere::Create(glm::vec3&, float, std::vector<glm::tvec3<float, (glm::precision)0u> >&, int)’:
./network/icosphere.cpp:46:36: error: call of overloaded ‘addVertex(glm::vec3)’ is ambiguous
  sphere.addVertex(glm::vec3(-1,t,0));
                                    ^
./network/icosphere.cpp:46:36: note: candidates are:
./network/icosphere.cpp:19:5: note: int IcoSphere::addVertex(glm::vec3)
 int IcoSphere::addVertex(glm::vec3 p) {_addVertex(p);}
     ^
./network/icosphere.cpp:20:5: note: int IcoSphere::addVertex(const vec3&&)
 int IcoSphere::addVertex(const glm::vec3 &&p) {_addVertex(p);}
     ^

This doesn't make a whole lot of sense to me, why is it considering it an ambiguous call?

回答1:

When compiler dealing with function overloading resolution, it firstly gets all the viable functions, then ranks them and call the one with highest ranking.

However for example

type var;
void func(type);
void func(tpye&&);
func(var);

Both of the func methods have the same ranking. They are all exact match. No promotion or implicit type cast or anything else is needed. The same case for your question. So you may want to change

int addVertex(glm::vec3 p);

to

int addVertex(const glm::vec3& p);

because you're not aiming to change it. Some more about overload resolution and rvalue reference overload resolution, http://www.dcs.bbk.ac.uk/~roger/cpp/week20.htm, http://yapb-soc.blogspot.com/2015/01/rvalue-references-and-function.html