Lorenzo Pistone
Lorenzo Pistone

Reputation: 5188

function template precedency case

template<typename T, size_t length> void f(T (&)[length]){
    cout<<"array"<<endl;
}

template<typename T> void f(T&){
    cout<<"generic"<<endl;
}

template<typename T, typename enable_if<is_array<T>::value, int>::type =0> void f(T&){
    cout<<"generic (is array)"<<endl;
}

is there any case (that is, any T when calling f<T>()) in which the last version of the function template will be preferred on top of the others?

Upvotes: 1

Views: 65

Answers (2)

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153820

Overload resolution always only works on the arguments of a function, independent on whether it is a function template or not. For function templates the return type is used before overload resolution when deciding whether a function template is a candidate. Essentially, it works like this:

  1. A set of possible candidate functions is build. For this functions which possibly match the arguments are considered. When function templates are looked at it is also determined whether the interface of the function template can be instantiated with the deduced arguments and if not the function isn't included in the overload set.
  2. Once the overload set is build the best match is determined. This exclusively looks at the arguments and tries to find the function call in the candidate set which requires the lest amount of conversions. If there is a tie, non-template functions are preferred, except that functions taking C-style variadic arguments are the least preferred. If there isn't exactly one match found overload resolution fails either having found no candidate or an ambiguity.

In your above case the unconstrained version of f() and the one restricted to be only instantiated if the deduced type is an T[N] are equally good matches. That is, if you do pass an T[N] to just these you should get an ambiguity. However, if the template argumetns are deduced to match the first version this one takes precedence anyway due to partial ordering of function templates: it ends up to be a better match.

Upvotes: 0

celtschk
celtschk

Reputation: 19721

No. If T is an array type, the first version wins over the second and third function (otherwise the second and third function would be ambiguous). If T is not an array type, the third function is not available, thanks to enable_if, and since the first one doesn't match, the second one will be used.

Upvotes: 2

Related Questions