tags:

views:

116

answers:

1

hello

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
+5  A: 

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.

jpalecek
From @aaa on my deleted answer: @jpa So, presence of template is what makes a big difference?
GMan
@GMan: Yes, see edit.
jpalecek