C++ standard, overloaded function resolution/matching - c++

Does C++ standard guarantee the following?:
template<typename T>
void function(T (&)[1]);
template<typename T>
void function(T*);
int a[1];
function(a); // first function gets called, not second version

Yes, this is guaranteed, but the reason is different than what GMan says. The "array of length 1" overload will be selected because it is more specialized than the second in template functions partial order. Basically, it means that an argument in the form T(&)[1] will always match the second template argument in the form T*, so the first overload will always be selected when conversion sequences don't decide.
From 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 template function specialization,
or, if not that,
F1 and F2 are template functions, and the function template for F1 is
more specialized than the tem- plate
for F2 according to the partial
ordering rules described in 14.5.5.2,
or, if not that,
...
Normal functions are only affected by the first item; when any template functions are in the set of candidate functions, the second or third item can decide. The reason we want it like that is we want to be able to write seemingly ambiguous templated overloads. Eg.
template <class T> void f(T);
template <class T> void f(T*);
would otherwise be ambiguous for int*. In C++0x, you can even write declarations like:
template <class ...Ts> void f(const Ts&... args);
template <class T, class ... Ts> void f(const T& a, const Ts&... args);
and the second will be selected whenever there is at least one argument.

Related

C++ which template would be call if both template function match the argument list

template<class T>
void fn(T t){}
template<class T>
void fn(std::vector<T> vt){}
void f() {
std::vector<int> vt;
fn(vt);
}
I know that the second template function would be called, but i dont know the rules for template function matching.
Partial ordering takes place in the overload resolution for a call to a function template specialization.
Informally "A is more specialized than B" means "A accepts fewer types than B".
For this case, the 2nd fn is more specialized and wins in overload resolution, because it accepts types of instantiations of std::vector that is fewer than the 1st one, which could accept all the types.

Overload resolution with template parameters

I am having trouble understanding why the following leads to an ambiguous call:
#include <iostream>
// generic version f(X, Y)
template <class X, class Y>
void f(X x, Y y) {
std::cout << "generic" << std::endl;
}
// overload version
template <class X>
void f(X x, typename X::type y) {
std::cout << "overload" << std::endl;
}
struct MyClass {
using type = int;
};
int main() {
f(MyClass(), int()); // Call to f is ambiguous
}
I would expect the overload version, which is more specialised in the second argument than the generic version, to be selected as the best candidate. I know that if I change the overload version to
template <class X>
void f(X x, int y) {
std::cout << "overload" << std::endl;
}
then the call is resolved just fine, which means it has to do with the fact that X::type is a template dependent name, but still cannot work out why it fails. Any help is much appreciated.
First, we pick the viable candidates. Those are:
void f(MyClass, int); // with X=MyClass, Y=int
void f(MyClass, typename MyClass::type); // with X=MyClass
Those candidates both take the same arguments, so have equivalent conversion sequences. So none of the tiebreakers based on those apply, so we fall back to the last possible tiebreaker in [over.match.best]:
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 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.
So we try to order the two function templates based on the partial ordering rules, which involve synthesizing a unique type for each template parameter and attempting to perform template deduction against each over overload. But with a key additional relevant rule from [temp.deduct.partial]:
Each type nominated above from the parameter template and the corresponding type from the argument
template are used as the types of P and A. If a particular P contains no template-parameters that participate
in template argument deduction, that P is not used to determine the ordering.
So what does this mean. First, let's try to deduce the generic version from the overload. We pick synthetic types UniqueX (for X) and UniqueX_type (for typename X::type) and see if we can invoke the generic function. This succeeds (with X=UniqueX and Y=typename X::type).
Let's try the inverse. We pick a UniqueX (for X) and a UniqueY (for Y) and try to perform template deduction. For the first P/A pair, this trivially succeeds. But for the second argument, X is a non-deduced context, which you would think would mean that template deduction fails. BUT as per the bolded part of the quote, we just skip this P/A pair for the purposes of ordering. So, since the first P/A pair succeeded, we consider the entire deduction process to have succeeded.
Since template deduction succeeds in both directions, we cannot pick one function or the other as being more specialized. Since there are no further tiebreakers, there is no single best viable candidate, so the call is ambiguous.
When the second overload is changed to:
template <class X> void f(X, int);
the part of the process that changes is that deduction now fails in one direction. We can deduce X=UniqueX but the second pair has a parameter of type int and an argument of type UniqueY, which will not work, so this direction fails. In the reverse direction, we can deduce X=UniqueX and Y=int. That makes this overload more specialized that the generic overload, so it would be preferred by the last tiebreaker I originally mentioned.
As an addendum, note that partial ordering of templates is complicated. Consider:
template <class T> struct identity { using type = T; };
template <class T> void foo(T ); // #1
template <class T> void foo(typename identity<T>::type ); // #2
template <class T> void bar(T, T); // #3
template <class T> void bar(T, typename identity<T>::type ); // #4
foo(0); // calls #1, #2 isn't even viable
foo<int>(0); // calls #2
bar(0,0); // calls #3! we fail to deduce 3 from 4, but we succeed
// in deducing 4 from 3 because we ignore the second P/A pair!

gcc vs. clang, msvc and icc: Is this function call ambiguous?

All compilers I could get my hands on agree that this is fine:
template <typename Check, typename... T>
auto foo(Check, T...) -> void;
template <typename... T>
auto foo(int, T...) -> void;
int main()
{
foo(7, "");
}
However, the following code (with a leading template parameter that cannot be deduced from the function parameters) is ambiguous according to gcc:
template <typename X, typename Check, typename... T>
auto bar(Check, T...) -> void;
template <typename X, typename... T>
auto bar(int, T...) -> void;
int main()
{
bar<void>(7, ""); // ambiguous according to gcc
bar<void>(7); // just fine
}
On the other hand, clang, msvc and icc are quite happy with this.
Which compiler is right?
References to the respective sections of the standard preferred.
This is core issue 200.
The description of how the partial ordering of template functions is
determined in 14.5.6.2 [temp.func.order] paragraphs 3-5 does not make
any provision for nondeduced template parameters. For example, the
function call in the following code is ambiguous, even though one
template is "obviously" more specialized than the other:
template <class T> T f(int);
template <class T, class U> T f(U);
void g() {
f<int>(1);
}
The reason is that neither function parameter list allows template parameter T to be deduced; both deductions fail, so neither
template is considered more specialized than the other and the
function call is ambiguous.
The resolution of core issue 214, which this one was reduced to, introduced [temp.deduct.partial]/11:
In most cases, all template parameters must have values in order for deduction to succeed, but for partial ordering purposes a template parameter may remain without a value provided it is not used in the types being used for partial ordering.
Apparently GCC's implementation of this wording is buggy once packs come into play.
IMHO I believe that GCC is wrong and CLANG is correct here. I'll try to justify my claim below:
According to the standard §14.8.3/p1 Overload resolution [temp.over] (Emphasis Mine):
A function template can be overloaded either by (non-template)
functions of its name or by (other) function templates of the same
name. When a call to that name is written (explicitly, or implicitly
using the operator notation), template argument deduction (14.8.2)
and checking of any explicit template arguments (14.3) are performed
for each function template to find the template argument values (if
any) that can be used with that function template to instantiate a
function template specialisation that can be invoked with the call
arguments. For each function template, if the argument deduction and
checking succeeds, the template-arguments (deduced and/or explicit)
are used to synthesise the declaration of a single function template
specialisation which is added to the candidate functions set to be
used in overload resolution. If, for a given function template,
argument deduction fails or the synthesised function template
specialisation would be ill-formed, no such function is added to the
set of candidate functions for that template. The complete set of
candidate functions includes all the synthesised declarations and all
of the non-template overloaded functions of the same name. The
synthesised declarations are treated like any other functions in the
remainder of overload resolution, except as explicitly noted in
13.3.3.144
[Example:
template<class T> T max(T a, T b) { return a>b?a:b; }
void f(int a, int b, char c, char d) {
int m1 = max(a,b); // max(int a, int b)
char m2 = max(c,d); // max(char a, char b)
int m3 = max(a,c); // error: cannot generate max(int,char)
}
144) The parameters of function template specializations contain
no template parameter types. The set of conversions allowed on deduced
arguments is limited, because the argument deduction process produces
function templates with parameters that either match the call
arguments exactly or differ only in ways that can be bridged by the
allowed limited conversions. Non-deduced arguments allow the full
range of conversions. Note also that 13.3.3 specifies that a
non-template function will be given preference over a template
specialisation if the two functions are otherwise equally good
candidates for an overload match.
From the above we get that explicit template arguments will be checked and if checking succeeds then will be used to synthesise a specialisation that will be added to the candidate functions for overload resolution. Thus, the fact the you specify explicitly X is irrelevant for the process.
Also from the C++ standard §13.3.3/p1.7 Best viable function [over.match.best]:
F1 and F2 are function template specialisations, and the function
template for F1 is more specialised than the template for F2
according to the partial ordering rules described in 14.5.6.2.
Now from §14.5.6.2/p3 Partial ordering of function templates [temp.func.order] we get that in partial ordering parameters packs are also into play, so no problem also here.
Now:
template <typename X, typename... T>
auto bar(int, T...) -> void;
is more specialized than:
template <typename X, typename Check, typename... T>
auto bar(Check, T...) -> void;
Therefore calling:
bar<void>(7, "");
is not ambiguous.
Based on the above I believe that this is a GCC bug.

Overloading of template function in template class

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.

Why does compiler not throw compilation error?

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.