gpt4 book ai didi

c++ - SFINAE 和重载函数的地址

转载 作者:IT老高 更新时间:2023-10-28 23:21:57 26 4
gpt4 key购买 nike

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

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 没有问题,它指定 bar的类型显式。

但是,foo2 ,它通过 SFINAE 对 bar 的一个版本以外的所有版本禁用自身,编译失败并显示以下消息:

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] (工作草案,从函数调用中推断模板参数)在这种情况下的规则(强调我的):

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.

SFINAE 会在扣除结束后参与游戏,因此绕过标准规则无济于事。
有关更多详细信息,您可以在上面链接的项目符号末尾查看示例。

关于你的最后一个问题:

Is there a way to make foo2<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++ - SFINAE 和重载函数的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33624891/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com