Template function overload resolution

Consider this code:

#include <iostream>

void    func(int&)
{
  std::cout << "mutable" << std::endl;
}

void    func(const int&)
{
  std::cout << "const" << std::endl;
}

template<typename T>
void    tpl_func(T&)
{
  std::cout << "mutable_tpl" << std::endl;
}

template<typename T>
void    tpl_func(const T&)
{
  std::cout << "const_tpl" << std::endl;
}

class number
{
public:
  operator int&()
  {
    return nb_;
  }

  operator const int&()
  {
    return nb_;
  }

private:
  int   nb_ = 42;
};

int     main()
{
  number n;

  func(n);     // This produces: error: call to 'func' is ambiguous
  tpl_func(n); // This compiles fine
}

      

Tested with clang3.5

Questions:

  • Why is the overload resolution for template functions not ambiguous?
  • What rules determine which overload is selected?
+3


source to share


2 answers


Because in func(n)

there is an implicit function call (operator int-conversion), which is ambiguous (you can choose either of the two), and in tpl_func(n)

you are NOT int-convertting, that is, the template outputs tpl_func<number>(number &)

, since it n

is an lvalue.



+3


source


func(n);

requires conversion, both func

are viable, and overload is ambiguous.



tpl_func(n);

has an exact match ( template<typename T> void tpl_func(T&)

).

+1


source







All Articles