接受指向类成员函数的指针的模板参数
Template parameter accepting pointer to class member function
#include <utility>
class Base {
public:
virtual ~Base() {}
virtual void base() {}
};
class Derived : public Base {
public:
virtual void derived() {}
};
template<typename... Params>
using MemberFuncPtr = void(Derived::*)(Params...);
template<typename... Params, typename... Args>
void wrapper(MemberFuncPtr<Params...> ptr, Args&&... args)
{
Derived* d = new Derived();
(d->*ptr)(std::forward<Args>(args)...);
delete d;
}
int main()
{
wrapper(&Derived::derived);
wrapper(&Derived::base);
return 0;
}
尝试运行此代码(GCC 7.0)会给我以下错误:
prog.cc: In function 'int main()':
prog.cc:33:27: error: no matching function for call to 'wrapper(void (Base::*)())'
wrapper(&Derived::base);
^
prog.cc:18:6: note: candidate: template<class ... Params, class ... Args> void wrapper(MemberFuncPtr<Params ...>, Args&& ...)
void wrapper(MemberFuncPtr<Params...> ptr, Args&&... args)
^~~~~~~
prog.cc:18:6: note: template argument deduction/substitution failed:
prog.cc:33:27: note: mismatched types 'Derived' and 'Base'
wrapper(&Derived::base);
^
我真的不明白为什么基类的方法是一个问题?它也是派生类的一种方法。我做了简单的测试,将Derived::base
分配给Derived::*ptr
类型并且有效。
我真的不明白为什么基类的方法是一个问题?
这只是类型是什么的问题。&Derived::derived
的类型是void (Derived::*)()
,但&Derived::base
的类型是void (Base::*)()
。这与void (Derived::*)(Args...)
不符,所以演绎失败。模板扣除不允许转换,即使在这种情况下存在有效的转换。
我做了简单的测试,我将
Derived::base
分配给Derived::*ptr
类型并且有效。
这:
MemberFuncPtr<> d = &Derived::base;
wrapper(d);
工作是因为现在d
的类型是正确的(它现在确实匹配void (Derived::*)(Args...)
),并且第一行很好,因为它可以将指向基类成员的指针转换为指向派生类成员的指针是有效的。
我真的不明白为什么基类的方法是一个问题?
@Barry在他的回答中已经解释了原因。
作为旁注,请注意,您可以进一步概括它并使其正常工作:
// ...
template<typename T, typename... Params>
using MemberFuncPtr = void(T::*)(Params...);
template<typename T, typename... Params, typename... Args>
void wrapper(MemberFuncPtr<T, Params...> ptr, Args&&... args)
{
// ...
}
相关文章:
- 为函数定义符号不明确的指针参数
- 构造函数 (C++) 中的 char 指针参数存在问题
- 按引用调用与按指针参数调用的差异 前递增和后递增
- 为什么具有指针参数的成员函数需要指向指针的指针?
- 通过引用函数传递指针参数是什么意思?
- 从double到double*的指针参数
- void 函数中的指针参数返回不一致的值
- 无法向上转换指针到指针参数
- 将数组动态分配到具有指针参数的函数中
- 模板函数指针参数与构造函数参数
- 使用通用函数指针参数化函数模板的简洁方法
- 如何为C++字符串分配空指针参数?
- C++带有指针参数的函数
- 指针参数的默认值
- 将常量添加到函数模板指针参数
- 如何传递unique_ptr<T>代替原始*输出*指针参数?
- 不带星号的函数指针参数
- 功能指针参数参数转换为const
- 将指针参数传递给双指针参数
- 如何调试指针参数是否通过函数修改