我的函数模板有一个函数指针(或成员函数指针)参数。函数指针可以接受任何参数,参数类型将被推断。在参数列表的末尾,我希望函数模板接受与函数指针参数相同的参数。
template<typename R, typename... Args>
void f(R(*fp)(Args...), Args... args);
当参数类型不完全匹配时,问题就开始了,例如,假设fp
接受Base*
,而f
的调用者给了你一个Derived*
,或者fp
接受double
,而调用者放入0
(类型为int
)。
有没有什么方法可以告诉编译器只根据fp
推断Args
,并且“只使用”args
的推断类型,而不尝试根据它们绑定的参数来匹配它们?
2条答案
按热度按时间jjhzyzn01#
我找到了一个有效的解决方案。我不知道的术语是非推导上下文。例如,范围解析运算符
::
左边的所有内容都是非推导的。在C20中,您可以使用std::type_identity_t
人工创建这样的上下文,在C14和C ++17中,您可以创建自己的type_identity_t
。所以你会用
关于完美转发,当
fp
通过引用或值接受参数时,f
也会这样做。对于std::forward
,一个通过值的参数将被移动,一个引用参数将被引用。vaj7vani2#
一种选择是为both1推导不同的类型,并使用SFINAE或概念在以下情况下禁用重载:
此选项与
std::type_identity
one的一个区别是,当您使用需要转换为fp
的参数调用f
时,例如。在
std::type_identity
的情况下,转换是在调用方完成的(即,当您调用f
时),而使用上面的选项时,转换是在您调用f
内部的fp
时完成的。1你也可以使用一个泛型函数类型,就像注解中建议的那样,这取决于你在
f()
中做了什么。