c – SFINAE和重载功能的地址

我正在尝试在另一个函数的参数(foo1 / foo2)的上下文中解析重载函数(bar)的地址.
struct Baz {};

int bar() { return 0; }
float bar(int) { return 0.0f; }
void bar(Baz *) {}

void foo1(void (&)(Baz *)) {}

template <class T,class D>
auto foo2(D *d) -> void_t<decltype(d(std::declval<T*>()))> {}

int main() {
    foo1(bar);      // Works
    foo2<Baz>(bar); // Fails
}

foo1没有问题,明确指定栏的类型.

但是,foo2通过SFINAE禁用其他版本的所有版本,无法使用以下消息进行编译:

main.cpp:19:5: Fatal error: no matching function for call to 'foo2'
    foo2<Baz>(bar); // Fails
    ^~~~~~~~~
main.cpp:15:6: note: candidate template ignored: Couldn't infer template argument 'D'
auto foo2(D *d) -> void_t<decltype(d(std::declval<T*>()))> {}
     ^
1 error generated.

我的理解是,C不能同时解析重载函数的地址并执行模板参数推导.

是原因吗有没有办法使foo2< Baz>(bar); (或类似的东西)编译?

解决方法

评论中提到,[14.8.2.1/6](工作草案,从函数调用中推导出模板参数)在这种情况下规则(强调我的):

WhenPis 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.

一旦扣除结束,SFINAE就会参与到游戏中,因此它无助于解决标准规则.
有关详细信息,可以在上面列出的项目符号的末尾看到示例.

关于你的最后一个问题:

Is there a way to makefoo2<Baz>(bar); (or something similar) compile ?

两种可能的选择:

>如果你不想修改foo2的定义,你可以调用它:

foo2<Baz>(static_cast<void(*)(Baz *)>(bar));

这样你就可以从过载集中明确地选择一个函数.
>如果允许修改foo2,可以将其重写为:

template <class T,class R>
auto foo2(R(*d)(T*)) {}

它或多或少是你以前的,在这种情况下没有decltype和返回类型,你可以自由地忽略.其实你不需要使用任何SFINAE的功能去做,扣除就够了.在这种情况下,foo2< Baz>(bar);正确解决

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...