mardi 23 janvier 2018

Why c++ template accepting array is not more specialized than one accepting pointer?

Why next two template declarations are ambiguous (so no one is more specialized than another)? I know this question was raised many times here, but usually people answer how to resolve ambiguity, not why it's happened.

I. template <class T> void func(char* buf, T size) {}

II. template <std::size_t N> void func(char (&buf)[N], std::size_t size) {}

Trying to pass steps of a standard c++14 to resolve partial function template ordering (14.5.6.2):

To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs (14.5.3) thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template.

Transformed I function template's function type is: void func(char*, U1), where U1 is some unique synthetic type.

Transformed II function template's function type is: void func(char (&buf)[N1], std::size_t), where N1 is some unique synthetic value.

Using the transformed function template’s function type, perform type deduction against the other template as described in 14.8.2.4.

Case 1.

Parameter template: template <std::size_t N> void func(char (&buf)[N], std::size_t size). Transformed argument template: void func(char*, U1).

Trying to deduce template parameters. "char (&buf)[N]" can't be deduced from "char*" type. U1 doesn't match std::size_t type too. Failed.

Case 2.

Parameter template: template <class T> void func(char* buf, T size). Transformed argument template: void func(char (&buf)[N1], std::size_t).

Trying to deduce template parameters. First argument of parameter template is not type at all and it's compatible with a char[]. T should be deduced to std::size_t.

So template II should be more specialized and should be selected from next code:

char buf[16];
func(buf, static_cast<std::size_t>(16));

Why it's not true for gcc 5.3 and for clang 4.0?

Aucun commentaire:

Enregistrer un commentaire