mardi 29 septembre 2015

Overload resolution produces ambiguous call when template parameters added

In the following code the compiler can successfully resolve the call to f() to call f(int&, const char*).

The call to g(), however, is ambiguous. It lists all four overloads as the possible overload set. If I remove , typename T2, std::size_t I from the template argument list for the array argument, and hard code them instead, there is no ambiguity and the compiler picks g(T&, const char*).

How is it that adding the two template arguments makes this ambiguous? I can see how, though decay and casting, it could resolve to any one of the overloads, but I cannot figure out how adding those template parameters introduces the ambiguity.

I have testing this on Clang 3.8 (unreleased) and VC++ 2015.

#include <string>

void f(int&, const char*){}
void f(int&, char(&)[8]){}
void f(int&, bool){}
void f(int&, const std::string&){}

template <typename T>
void g(T&, bool){}
template <typename T>
void g(T&, const char*){}
template <typename T>
void g(T&, const std::string&){}
template <typename T, typename T2, std::size_t I>
void g(T&, T2(&)[I]){}

int main(int argc, char* argv[])
{
   int i = 1;
   f(i, "       ");
   g(i, "       ");
   return 0;
}

Aucun commentaire:

Enregistrer un commentaire