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

时间:2018-01-28 10:43:06

标签: c++ templates language-lawyer c++17

this question的后续行动。假设占位符可用于推导构成非类型模板参数的函数指针的结果类型。 c ++ 17是否允许在传递给模板函数名称时执行重载解析 - 不知道结果类型,执行隐式转换需要什么?

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

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

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

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

1 个答案:

答案 0 :(得分:7)

是的,根据very bullet Rakete1111 pointed out允许。并且没有必要假设它可以完成,它是根据[dcl.type.auto.deduct]/4的占位符类型推导规则完成的,强调我的:

  

如果占位符是自动类型说明符,则推导出类型T'   使用模板参数的规则确定替换T.   扣除。通过替换auto的出现来从T获得P.   要么是新发明的类型模板参数U,要么是   初始化是copy-list-initialization,用   的std :: initializer_list。 使用规则为U减去一个值   函数调用的模板参数推导,其中P是a   函数模板参数类型和相应的参数是e。   如果扣除失败,则声明格式不正确。否则,T'   通过将推导的U代入P来获得。

[temp.deduct.call]/6哪个段落与您的用例有关:

  

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

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

  •   
  • 如果参数是重载集(不包含函数模板),则尝试使用每个参数推导出试验参数推导   成员。 如果仅扣除其中一个,则扣除成功   重载集成员,该成员用作参数值   扣除。如果扣除成功超过一个成员   过载设置将参数视为非推导的上下文。

  •   

所以你有它的荣耀。