非类型模板参数中的占位符类型是否涉及作为模板参数传递的函数的重载解析?



这个问题的后续。假设占位符可用于推断构成非类型模板参数的函数指针的结果类型。c++17 是否允许在传递给模板函数名称时执行重载解析 - 在不知道结果类型的情况下,执行隐式强制转换需要

template <auto(*)(int)>
struct Foo { };
int bar(int);
float bar(float);
int main() {
static_cast<void>(Foo<bar>{});
}

[gcc] 和 [clang] 似乎接受了代码。

是的,根据Rakete1111指出的子弹,这是允许的。而且没有必要只是假设它可以完成,它是根据 [dcl.type.auto.deduct]/4 中的占位符类型扣除规则完成的,强调我的:

如果占位符是自动类型说明符,则推导的类型为 T' 替换 T 是使用模板参数的规则确定的 演绎。通过将 auto 的出现次数替换为 要么是新发明的类型模板参数 U,要么是 初始化是复制列表初始化,使用 标准::initializer_list。使用 从函数调用中推导模板参数,其中 P 是 函数模板参数类型,对应的参数为 e。如果扣除失败,则声明格式不正确。否则,T' 通过将推导的 U 代入 P 而获得。

其中 [temp.deduct.call]/6 有这一段,与您的用例有关:

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

  • 如果参数是包含一个或多个函数模板的重载集,则该参数将被视为非推导上下文。

  • 如果参数是重载集(不包含函数模板),则尝试使用每个 集合的成员。如果仅对其中一个成功扣除 重载集成员,该成员用作 扣除。如果多个成员的扣除成功 重载集 该参数被视为非推导上下文。

所以你有它所有的荣耀。

最新更新