3

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 the template functions not ambiguous ?
  • What rules determine which overload is chosen ?
3
  • just out of curiosity, what does tpl_func print? Commented Oct 22, 2014 at 16:40
  • @Creris It prints "mutable_tpl" Commented Oct 22, 2014 at 16:48
  • 1
    well yes as mentioned below with two answers, it is actually not ambiguous. It would most likely become ambiguous if you called tpl_func<int>(n); Commented Oct 22, 2014 at 16:49

2 Answers 2

3

Because in func(n) there's an implicit function call (the int-conversion operator) which is ambiguous (you could choose any of the two) and in tpl_func(n) you're NOT int-converting, i.e. the template deduces to tpl_func<number>(number &) since n is lvalue.

Sign up to request clarification or add additional context in comments.

Comments

1

func(n); requires a conversion, both func are viable and overload is ambiguous.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.