2

I have the following class:

template<typename T>
class List {

    void Add(T& item) {//GOOD STUFF}
    void Add(T item) {//More STUFF}
    void Remove(T item) {//STUFF}
};

I am trying to use it like the following

List<MyClass> list;
MyClass obj;
list.Add(obj); //Here the compiler gets angry :((

Regarding the question I have already found the following three SO questions, but I am still not able to call either of the methods.
Ambiguous call with overloaded r-value reference function
function call ambiguity with pointer, reference and constant reference parameter
Ambiguous Reference/Value Versions of Functions

gsamaras
  • 71,951
  • 46
  • 188
  • 305
Hasan Emrah Süngü
  • 3,488
  • 1
  • 15
  • 33
  • I am sorry I will fix now!! – Hasan Emrah Süngü Dec 08 '18 at 16:38
  • 1
    Considering the names of the function `Add(T& item)` is certainly a mistake! Viewing the signature I suppose the intent is to connect the item to the chain of elements without ownership. So maybe `bind` or `connect` would be a less surprising name. That will avoid you surprising heterogeneous overload behavior. That is bad design. – Oliv Dec 08 '18 at 16:49
  • Yeah I was thinking that `item` being added to `List` will not be owned by the `List` itself. Then I found myself fiddling with function signatures, overloads, references etc – Hasan Emrah Süngü Dec 08 '18 at 16:51
  • So I would definitively use a special name, and explicitly disable r-value reference binding: `void bind(T& item){/*...*/} void bind(T&& item) =delete;` – Oliv Dec 08 '18 at 17:06

1 Answers1

2

It is ambiguous which function you intend to call, because any l-value being passed as argument to a function can be implicitly converted to a reference, so the ambiguity is unavoidable, as said in Function Overloading Based on Value vs. Const Reference.

You could change this:

void Add(T item) {}

to this:

void Add(T&& item) {}

Live demo

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • Thanks for the answer. Could you please tell me the difference between the two? If i am not mistaken T&& is move semantics – Hasan Emrah Süngü Dec 08 '18 at 16:44
  • 1
    You are welcome @EmrahSüngü, I updated my answer with a somewhat related link to your question. I know it's not an exact duplicate, but it should explain it to you. Hope that helps. – gsamaras Dec 08 '18 at 16:46
  • I see I seee `any l-value being passed as argument to a function can be implicitly converted to a reference, so the ambiguity is unavoidable.` – Hasan Emrah Süngü Dec 08 '18 at 16:49
  • could you please tell me that after I change the signature to T&& how can I call either of the methods? – Hasan Emrah Süngü Dec 08 '18 at 16:55
  • @EmrahSüngü updated my answer again, now the Live demo should answer your question. ;) – gsamaras Dec 08 '18 at 17:03