[英]C++ template argument deduction for pointers to overloaded member function
I'm currently working on a template function that deals with pointers to member functions.我目前正在研究处理指向成员函数的指针的模板函数。 It originally looked like this:
它最初是这样的:
template <typename C, typename RT, typename... P>
auto CreateTestSuite(RT(C::* pFunc)(P...))
{...}
However, I soon found that if I try to pass to it a pointer to a const member function, the template will not recognize this.但是,我很快发现,如果我尝试将指向 const 成员函数的指针传递给它,模板将无法识别这一点。 So I then added this overloaded version:
所以我然后添加了这个重载版本:
template <typename C, typename RT, typename... P>
auto CreateTestSuite(RT(C::* pFunc)(P...) const)
{...}
For two different member functions with const and non-const respectively, it works fine.对于分别具有 const 和非常量的两个不同成员函数,它工作正常。 However, if I try to call
CreateTestSuite
for a pointer to an overloaded member function, a problem arises.但是,如果我尝试调用
CreateTestSuite
以获得指向重载成员函数的指针,则会出现问题。
For example, assume I have the following class A:例如,假设我有以下 A 类:
class A
{
public:
return_type test(...) {...}
return_type test(...) const {...}
};
And now when I try to make the function call现在当我尝试进行函数调用时
CreateTestSuite(&A::test);
The compiler will not be able to tell which overloaded version I am using.编译器将无法判断我使用的是哪个重载版本。 In addition, this problem cannot be solved by explicitly specifying the template arguments, because they are the same for the overloaded versions of
CreateTestSuite
.此外,这个问题不能通过显式指定模板参数来解决,因为它们对于
CreateTestSuite
的重载版本是相同的。
How do I explicitly select from the two versions?如何从两个版本中明确选择?
Edit: I can accept minor modification to CreateTestSuite
.编辑:我可以接受对
CreateTestSuite
微小修改。
Many thanks.非常感谢。
You can add an additional template bool
to CreateTestSuite()
to decide whether to choose const
-qualified member functions:您可以向
CreateTestSuite()
添加一个额外的模板bool
来决定是否选择const
限定成员函数:
#include <type_traits>
template <bool IsConst = false, typename C, typename RT, typename... P>
auto CreateTestSuite(RT(C::* pFunc)(P...), std::enable_if_t<!IsConst>* = nullptr)
{ }
template <bool IsConst, typename C, typename RT, typename... P>
auto CreateTestSuite(RT(C::* pFunc)(P...) const, std::enable_if_t<IsConst>* = nullptr)
{ }
Then you can explicitly specify IsConst
to call CreateTestSuite()
:然后您可以显式指定
IsConst
来调用CreateTestSuite()
:
CreateTestSuite(&A::test);
CreateTestSuite<true>(&A::test);
CreateTestSuite<false>(&A::test);
As your issue is just to select the right overload, you might write helpers:由于您的问题只是选择正确的重载,您可以编写助手:
template <typename C, typename RT, typename... P>
constexpr auto non_const_overload(RT (C::*pFunc)(P...)) { return pFunc; }
template <typename C, typename RT, typename... P>
constexpr auto const_overload(RT (C::*pFunc)(P...) const) { return pFunc; }
With usage随着使用
CreateTestSuite(non_const_overload(&A::test));
CreateTestSuite(const_overload(&A::test));
Note : You might need 24 helpers to handle all combinations with volatile
, reference to this and C-ellipsis.注意:您可能需要 24 个助手来处理所有与
volatile
组合,参考 this 和 C-ellipsis。
or MACRO (with c++20 lambda immediate-called):或 MACRO(立即调用 c++20 lambda):
#define OVERLOAD(name, /*qualifiers*/...) []<typename C, typename RT, typename... P>(RT (C::*pFunc)(P...) __VA_ARGS__){ return pFunc; }(name)
CreateTestSuite(OVERLOAD(&A::test)); /*no const*/
CreateTestSuite(OVERLOAD(&A::test,)); /*no const*/
CreateTestSuite(OVERLOAD(&A::test, const));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.