Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can placeholder type in non-type template parameter involve overload resolution of the function passed as a template argument?

A follow-up of this question. Assuming placeholder can be used to deduce result type of the function pointer constituting non-type template parameter. Does c++17 allows to perform overload resolution on passed to the template function name - without the knowledge of the result type, that would be needed to perform implicit casting?

template <auto(*)(int)>
struct Foo { };

int bar(int);
float bar(float);

int main() {
    static_cast<void>(Foo<bar>{});
}

[gcc] as well as [clang] seem to accept the code.

like image 550
W.F. Avatar asked Jan 28 '18 10:01

W.F.


1 Answers

Yes, it's allowed according to the very bullet Rakete1111 pointed out. And there's no need to just assume it can be done, it's done according to the rules of placeholder type deduction at [dcl.type.auto.deduct]/4, emphasis mine:

If the placeholder is the auto type-specifier, the deduced type T' replacing T is determined using the rules for template argument deduction. Obtain P from T by replacing the occurrences of auto with either a new invented type template parameter U or, if the initialization is copy-list-initialization, with std​::​initializer_­list. Deduce a value for U using the rules of template argument deduction from a function call, where P is a function template parameter type and the corresponding argument is e. If the deduction fails, the declaration is ill-formed. Otherwise, T' is obtained by substituting the deduced U into P.

Where [temp.deduct.call]/6 has this paragraph, pertaining to your use case:

When P is a function type, function pointer type, or pointer to member function type:

  • If the argument is an overload set containing one or more function templates, the parameter is treated as a non-deduced context.

  • If the argument is an overload set (not containing function templates), trial argument deduction is attempted using each of the members of the set. If deduction succeeds for only one of the overload set members, that member is used as the argument value for the deduction. If deduction succeeds for more than one member of the overload set the parameter is treated as a non-deduced context.

So there you have it in all its glory.

like image 151
StoryTeller - Unslander Monica Avatar answered Nov 14 '22 23:11

StoryTeller - Unslander Monica