GCC 4.7.2 does not fail when the -std=c++98 flag is -std=c++98 . In fact, in C ++ 98 (as in C ++ 03) links to links are not destroyed.
Trying to create an instance f<int&> , where T = int& , yields the following function signature (here I intentionally switch the position of the type of the argument T and the qualifier const , which is allowed, since const T& the same as T const& ):
void f(int& const& t)
The above is not legal in C ++ 98 nor in C ++ 03. Consequently, this is the error you get from GCC 4.7.2:
Compilation finished with errors: source.cpp: In function 'int main()': source.cpp:15:14: error: no matching function for call to 'f(int&)' source.cpp:15:14: note: candidate is: source.cpp:5:6: note: template<class T> void f(const T&) source.cpp:5:6: note: template argument deduction/substitution failed: source.cpp: In substitution of 'template<class T> void f(const T&) [with T = int&]': source.cpp:15:14: required from here source.cpp:5:6: error: forming reference to reference type 'int&'
However, if you use the -std=c++11 flag, then the compiler collapses the links when creating the template instance: the lvalue link to the lvalue link becomes the lvalue link:
void f(int& const& t) == void f(int& t)
Here the const qualifier is discarded because it is applied to the link , not to the reference object. Since links cannot be reassigned, they are const in nature, therefore const is considered redundant and remote. See this Q&A on SO for an explanation.
This gives the lvalue link to the lvalue link, which resolves into a simple lvalue reference. Therefore, a signature on the right side is created.
The above is a viable candidate for call resolution for f<int&>(a) and therefore it compiles without errors.
source share