Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are function template parameters T& and T&& ambiguous? [duplicate]

While playing with universal references, I came across this instance where clang and gcc disagree on overload resolution.

#include <iostream>

struct foo {};

template<typename T>
void bar(T&) { std::cout << "void bar(T&)\n"; }

template<typename T>
void bar(T&&) { std::cout << "void bar(T&&)\n"; }

int main()
{
    foo f;
    bar(f);  // ambiguous on gcc, ok on clang
}

gcc reports the call above is ambiguous. However, clang selects the T& overload and compiles successfully.

Which compiler is wrong, and why?

Edit:
Tested the same code on VS2013 Preview, and it agrees with clang; except Intellisense, which is on gcc's side :-)

like image 416
Praetorian Avatar asked Jul 31 '13 19:07

Praetorian


People also ask

What are template parameters?

In UML models, template parameters are formal parameters that once bound to actual values, called template arguments, make templates usable model elements. You can use template parameters to create general definitions of particular types of template.

What is the difference between template typename T and template T?

There is no difference. typename and class are interchangeable in the declaration of a type template parameter.

Can a template be a template parameter?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)

What is true about function templates?

Explanation: As a template feature allows you to write generic programs. therefore a template function works with any type of data whereas normal function works with the specific types mentioned while writing a program. Both normal and template function accepts any number of parameters.


1 Answers

The "universal reference" deduces the parameter to foo&. The first template also deduces the parameter to foo&.

C++ has a partial ordering rule for function templates that makes T& be more specialized than T&&. Hence the first template must be chosen in your example code.

like image 133
Johannes Schaub - litb Avatar answered Oct 20 '22 12:10

Johannes Schaub - litb