获取指向基 class 的受保护方法的指针并将其传递给不同的 class
Taking a pointer to a protected method of the base class and passing it to a different class
template <typename... Arguments>
class CCallback
{
public:
template <class TargetClass>
CCallback(TargetClass * target, void (TargetClass::*targetMethod)(Arguments...))
{
}
};
struct TargetClassBase
{
protected:
void f() {}
};
struct TargetClassChild : TargetClassBase
{
void g() {}
void test()
{
CCallback<> callback(this, &TargetClassChild::f);
}
} child;
void main()
{
}
该代码无法在 MSVC 2013 中编译:
error C2660: 'CCallback<>::CCallback' : function does not take 2
arguments
我不明白为什么会出现这个特定错误,以及如何让它起作用。没有关于编译器记录的错误的更多详细信息。
而且,当然,我无法正确指定该方法属于基 class (&TargetClassBase::f
)- 禁止使用指向非公共基方法的指针。
您的代码存在问题,编译器无法在 CCallback
的构造函数中推断出模板类型 TargetClass
。这是因为您将 TargetClassChild*
和 void (TargetClassBase::*)()
类型的参数传递给构造函数。这不是错字。即使你写 &TargetClassChild::f
这个表达式仍然有类型:指向在 class TargetClassBase 而不是 TargetClassChild 中返回 void 的函数的指针不出所料。
此类问题可以通过两种方式解决:
- 您可以显式指定模板类型,但在这种特殊情况下无法完成,因为在 C++ 中无法将模板参数显式传递给构造函数,因为构造函数没有名称(根据 §14.5. c++ 标准的 2.5).
- 将适当类型的参数传递给函数。在这种情况下,只需将您的函数转换为适当的类型,例如
static_cast<void (TargetClassChild::*)()>(&TargetClassChild::f)
扩展 robal 的完全正确答案,我重写了 class 的构造函数,这样我就不需要手动类型转换了:
template <class TargetInstanceClass, class TargetMethodClass>
CCallback(TargetInstanceClass * target, void (TargetMethodClass::*targetMethod)(Arguments...))
{
void (TargetInstanceClass::*targetInstanceMethod)(Arguments...) = static_cast<void (TargetInstanceClass::*targetInstanceMethod)(Arguments...)>(targetMethod);
}
template <typename... Arguments>
class CCallback
{
public:
template <class TargetClass>
CCallback(TargetClass * target, void (TargetClass::*targetMethod)(Arguments...))
{
}
};
struct TargetClassBase
{
protected:
void f() {}
};
struct TargetClassChild : TargetClassBase
{
void g() {}
void test()
{
CCallback<> callback(this, &TargetClassChild::f);
}
} child;
void main()
{
}
该代码无法在 MSVC 2013 中编译:
error C2660: 'CCallback<>::CCallback' : function does not take 2 arguments
我不明白为什么会出现这个特定错误,以及如何让它起作用。没有关于编译器记录的错误的更多详细信息。
而且,当然,我无法正确指定该方法属于基 class (&TargetClassBase::f
)- 禁止使用指向非公共基方法的指针。
您的代码存在问题,编译器无法在 CCallback
的构造函数中推断出模板类型 TargetClass
。这是因为您将 TargetClassChild*
和 void (TargetClassBase::*)()
类型的参数传递给构造函数。这不是错字。即使你写 &TargetClassChild::f
这个表达式仍然有类型:指向在 class TargetClassBase 而不是 TargetClassChild 中返回 void 的函数的指针不出所料。
此类问题可以通过两种方式解决:
- 您可以显式指定模板类型,但在这种特殊情况下无法完成,因为在 C++ 中无法将模板参数显式传递给构造函数,因为构造函数没有名称(根据 §14.5. c++ 标准的 2.5).
- 将适当类型的参数传递给函数。在这种情况下,只需将您的函数转换为适当的类型,例如
static_cast<void (TargetClassChild::*)()>(&TargetClassChild::f)
扩展 robal 的完全正确答案,我重写了 class 的构造函数,这样我就不需要手动类型转换了:
template <class TargetInstanceClass, class TargetMethodClass>
CCallback(TargetInstanceClass * target, void (TargetMethodClass::*targetMethod)(Arguments...))
{
void (TargetInstanceClass::*targetInstanceMethod)(Arguments...) = static_cast<void (TargetInstanceClass::*targetInstanceMethod)(Arguments...)>(targetMethod);
}