1

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?

Silverlan
  • 2,783
  • 3
  • 31
  • 66
  • 5
    In most cases, overload resolution can't distinguish between passing by value and by reference. What are you hoping to achieve by the const rvalue-ref overload? – T.C. Feb 24 '15 at 16:29
  • I want it to use the reference-overload if possible, to remove the overhead of copying the object. However I also want it to be possible to pass a value directly, for convenience's sake. – Silverlan Feb 24 '15 at 16:49

1 Answers1

5

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

However for example, in

type var;
void func(type);
void func(type&&);
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

PROgram52bc
  • 98
  • 1
  • 1
  • 8
fmars
  • 139
  • 1
  • 4