非类型模板参数中的占位符类型可以涉及作为模板参数传递的函数的重载解析吗? [英] Can placeholder type in non-type template parameter involve overload resolution of the function passed as a template argument?

查看:76
本文介绍了非类型模板参数中的占位符类型可以涉及作为模板参数传递的函数的重载解析吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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] 以及

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

推荐答案

是的,根据

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:

如果占位符是自动类型说明符,则推导类型T' 使用模板参数规则确定替换T 扣除.通过将auto的出现替换为T,从T中获得P 一个新的发明类型模板参数U,或者 初始化是复制列表初始化,带有 std ::: initializer_list 使用以下规则推导U的值 从函数调用中推导出模板参数,其中P是一个 函数模板的参数类型,相应的参数为e. 如果推导失败,则声明格式错误.否则,T' 是通过将推导的U代入P来获得的.

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.

其中 [temp.deduct.call]/6 具有与您的用例有关的本段:

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

当P是函数类型,函数指针类型或指向成员的指针时 函数类型:

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.

这篇关于非类型模板参数中的占位符类型可以涉及作为模板参数传递的函数的重载解析吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆