Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 ambiguous overload when calling variadic function template

Could you please explain why I'm having error: call of overloaded ‘func(const Test&)’ is ambiguous despite the fact that I use explicit template instantiation?

#include <iostream>

struct Test {
};

void func(const Test &) {
  std::cout << "By Reference" << std::endl;
}

void func(const Test) {
  std::cout << "By Value" << std::endl;
}

template <typename... TArgs>
void wrap(TArgs... args) {
  func(args...);
}

int main() {
  Test t;
  wrap<const Test &>(t);
  return 0;
};

EDIT

The reason of ambiguity is a combination of two factors. The first is that simple overload rules applied in the call func(args...). The second is that simple functions cannot be overloaded by value and const reference. To ensure, one may replace the call wrap<const Test &>(t) with func(static_cast<const Test &>(t)). The error will still be there.

To solve the problem, one may use function template for func and value vs const reference template specialization as showed in the example provided by @lubgr

Thanks everybody to help me to demystify the concept.

like image 541
TruLa Avatar asked Sep 04 '18 10:09

TruLa


1 Answers

For the same reason the following calls are ambiguous:

#include <iostream>
void foo(int) { std::cout << "val" << std::endl; }
void foo(const int&) { std::cout << "ref" << std::endl; }

int main()
{
  int i = 1;
  foo(i);
}

See here for full discussion of that case.

like image 69
paler123 Avatar answered Sep 30 '22 02:09

paler123