Why does compiler allow this?
#include <iostream>
using namespace std;
template<typename T>
void func(T t)
{
cout<<"The value is :"<<t<<"\n";
}
template<>
void func<int>(int d) //Template Specialization
{
cout<<"Template function\n";
}
void func(int d) //Non-template function with same name & signature
{
cout<<"Non-template function\n";
}
int main()
{
func(4);
func(4.67);
func("TENE");
}
The answer to the question lies in section 13.3.3
Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
— for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,
— F1 is a non-template function and F2 is a function template specialization, or, if not that,
— F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 14.5.5.2, or, if not that, ...
So amongst the three choices (non-templated func, specialization of func<int>, and the generic template func<typename T>, the non-template version of func is the best. Since there is a perfect match here, there is no reason for the compiler to even look to the templated versions of the function.
Because this code is perfectly legal. See this article for resolution rules.
Related
Consider the following code:
#include <iostream>
#include <type_traits>
template <typename T>
class A
{
public:
// Allow func to be called if T is the const version of T2
// e.g., T is 'int const' and T2 is 'int'
template <typename T2,
typename = typename std::enable_if<
std::is_same<T, T2 const>::value>::type>
void func(A<T2> const &)
{
std::cout << "Conversion" << std::endl;
}
// Allow func to be called for same version of T
void func(A const &)
{
std::cout << "No conversion" << std::endl;
}
};
int main()
{
A<int const> a;
a.func(A<int const>{});
return 0;
}
This code, when compiled with GCC-8.3 compiles and produces the output No conversion - it selected the version of func that does not use std::enable_if. However, if I comment out the second version of func, it will still compile and now produce the output Conversion. In other words, both versions of func within A are usable for this method. Given that both overloads are viable, what specific rule is the compiler using to select func(A const &) over the other version (func(A<T2> const &))?
The rule is that if a non function template and a function template specialization have the same signature, then the non function template is chosen over the template specialization. This can be found in [over.match.best]/2
Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
[...]
F1 is not a function template specialization and F2 is a function template specialization [...]
You can read about overload resolution here. In particular
If any candidate is a function template, its specializations are generated using template argument deduction, and such specializations are treated just like non-template functions except where specified otherwise in the tie-breaker rules.
And then
Best viable function
For each pair of viable function F1 and F2, the implicit conversion sequences from the i-th argument to i-th parameter are ranked to determine which one is better [...]
F1 is determined to be a better function than F2 if implicit conversions for all arguments of F1 are not worse than the implicit conversions for all arguments of F2, and
[...]
4) [...] F1 is a non-template function while F2 is a template specialization
Basically the same rules apply in this simpler example:
#include<iostream>
template <typename T>
void foo(T i) { std::cout << "template" ; }
void foo(int i) { std::cout << "non template"; }
int main() {
foo(1); // non template
}
The following code passes asserts:
int foo() { return 1; }
template<typename T>
int foo() { return 2; }
int main() {
assert( 1 == foo() );
assert( 2 == foo<int>() );
return 0;
}
But to my understanding, according to Paragraph 13.3.3/1 of the C++11 Standard:
[...] Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then [...] F1 is a non-template function and F2 is a function template specialization [...]
It should not, because signatures end up to be the same. So why is there no ambiguity when foo<int>() is called? What am I missing?
The text you quote is rather dense; you have to read it carefully. "F1 is better than F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2)" -- that's true here, since the two conversion sequences are the same, hence, neither is worse than the other. So now you move to the last part: "and then F1 is a non-template function and F2 is a function template specialization". That's true, so F1 is a better match than F2. Substituting foo() and foo<int>() for F1 and F2, respectively, the rule says that foo() is a better match than foo<int>().
Whoops, I answered the wrong question. As the comment points out, the question is, why does explicitly calling foo<int>() not resolve to foo()? And the answer is, foo<int>() is a call to an explicit template instantiation, not a call to an overloaded function. Consider:
template <class Ty>
void f(Ty) { }
void f(int);
void g(int);
f(3.14); // calls f<double> (overloaded function call)
f(1); // calls f(int) (overloaded function call)
f<int>(3.14); // calls f<int> (explicit call of template instantiation)
g(3.14); // calls g(int)
In this example, f<int> is the name of a template specialization. It is not the general function named f, so there is no overloading to consider, just like the call to g(3.14).
I had created a Template Specialized function and a non template function with the same arguments. Since effectively both are same functions, I was not sure how C++ compiler would run it as now it has two same functions, one is a template specialized the other is a non template one. I was expecting this would result in a compiler error as compiler would find two functions with the same parameters and return type (In this case void foo(string) ). But looks like the non template version is the one that executes when this is called.
So is there a precedence when this is done?
Kindly let me know if I have misunderstood.
Code: This prints 'String Non-Template'
#include <iostream>
#include <string>
using namespace std;
template<typename T>
void foo(T input)
{
cout <<"Generic Template"<<endl;
}
template<>
void foo<string>(string input)
{
cout <<"String Template"<<endl;
}
void foo(string input)
{
cout <<"String Non-Template"<<endl;
}
int main() {
string input = "abc";
foo(input);
return 0;
}
A regular function is always preferred over a function template, even a specialization of the function template.
From the C++ Standard:
13.3.3 Best viable function [over.match.best]
1 Define ICSi(F) as follows:
...
Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
...
-- F1 is a non-template function and F2 is a function template specialization, or, if not that,
I have a templated operator in templated class and I want to change its behavior for specific type. My code:
#include <iostream>
template <typename N>
struct A {
int x;
template<typename T>
A& operator<<(const T& t) {
x += static_cast<int>(t);
return *this;
}
};
enum class B {
s,t
};
template <typename N>
A<N>& operator<<(A<N>& a, const B& b) {
a.x -= static_cast<int>(b);
return a;
}
int main() {
A<int> a{3};
std::cout << (a<<1).x << " " << (a << B::s).x;
}
g++-4.9 compiles it fine but clang-3.6 complains that it's ambiguous.
Note, that if class is not templated, than both of compilers compile it fine.
What is correct behavior?
Short summary: I believe this is a gcc bug in the template partial ordering rules, and that clang is correct. I filed bug 66914, although it's probably a duplicate of bug 53499 which I didn't notice until afterwards.
In the call
a << B::s;
We have two viable candidates:
template <typename T> A<int>::operator<<(const T& );
template <typename N> operator<<(A<N>&, const B& );
You can rewrite the member function to take a reference to the instance as the first argument, and write out both as instantiatons. So we have:
template <> operator<<(A<int>&, const B& ); // [T = B]
template <> operator<<(A<int>&, const B& ); // [N = int]
Since both are viable candidates, let's go through the rules in [over.match.best] to determine which one is the best viable candidate:
Given these definitions, a viable function F1 is defined to be a better function than another viable function
F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
— for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,
Nope, both take the exact same arguments, so the conversion sequences are identical.
— the context is an initialization by user-defined conversion [ ... ]
Nope, irrelevant.
— the context is an initialization by conversion function [ ... ]
Nope, irrelevant.
— F1 is not a function template specialization and F2 is a function template specialization, or, if not that,
Nope, both are function template specializations.
— F1 and F2 are function template specializations, and the function template for F1 is more specialized
than the template for F2 according to the partial ordering rules described in 14.5.6.2.
This is the most complicated of the rules. Ultimately, neither is more specialized than the other. Why? The member function is effectively:
template <typename T> A<int>& operator<<(A<int>&, const T& );
If we synthesized a type for T (call it Unique1), deduction would fail against the free function (since Unique1 wouldn't match B). On the other side, if we synthesized a type for N (call it Unique2), deduction would fail against the member function (since Unique2 wouldn't match int).
Since neither function is more specialized than the other, we've run out of bullet points. The function call should be ambiguous, this is a gcc bug.
This:
template <typename N>
A<N>& operator<<(A<N>& a, const B& b) {
a.x -= static_cast<int>(b);
return a;
}
is not an overload of your member operator (I'm sure there is a more correct way to say it from the standardese point of view), and not a specialization, it is a global template operator that participates in overload resolution.
From that point of view both are equally perfect matches so I think clang is correct.
I have this code:
template<
class T = const int &
> void f(T) {}
void f(const int &) {}
int main() {
f(0);
}
Why does it call the second one instead of first? I would think of them as being the same but they're clearly not as I do not get a redefinition error.
Because the second overload is not a template.
When a template function and a non-template function are both viable for resolving a function call, the non-template function is selected.
From Paragraph 13.3.3/1 of the C++ 11 Standard:
[...] Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then [...] F1 is a non-template function and F2 is a function template specialization [...]
One is a template and the other is not, they are definitely not the same.
Overload resolution is designed to prefer a non-template over a templated function, everything else being equal.