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](工作草案,从函数调用中推导出模板参数)在这种情况下规则(强调我的):
一旦扣除结束,SFINAE就会参与到游戏中,因此它无助于解决标准规则. 关于你的最后一个问题:
两种可能的选择: >如果你不想修改foo2的定义,你可以调用它: foo2<Baz>(static_cast<void(*)(Baz *)>(bar)); 这样你就可以从过载集中明确地选择一个函数. template <class T,class R> auto foo2(R(*d)(T*)) {} 它或多或少是你以前的,在这种情况下没有decltype和返回类型,你可以自由地忽略.其实你不需要使用任何SFINAE的功能去做,扣除就够了.在这种情况下,foo2< Baz>(bar);正确解决 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |