非类型模板函数指针指向const成员函数 [英] Non-type template function pointer to const member function
问题描述
我在写一个委托类,但它不能接受const成员函数。
这是一个测试用例:
I'm writing a delegate class but it fails to take const member functions. Here is a test case :
class foo
{
public:
void MemberFunction()
{
printf("non const member function\n");
}
void ConstMemberFunction() const
{
printf("const member function\n");
}
};
template <class C, void (C::*Function)()>
void Call(C* instance)
{
(instance->*Function)();
}
int main (int argc, char** argv)
{
foo bar;
Call<foo,&foo::MemberFunction>(&bar);
Call<foo,&foo::ConstMemberFunction>(&bar);
}
现在编译器(visual studio 2010)给我一个错误, const成员函数到一个非const函数:
Now the compiler (visual studio 2010) gives me an error he cannot convert the const member function to a non-const function :
2>..\src\main.cpp(54): error C2440: 'specialization' : cannot convert from 'void (__cdecl foo::* )(void) const' to 'void (__cdecl foo::* const )(void)'
2> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
2>..\src\main.cpp(54): error C2973: 'Call' : invalid template argument 'void (__cdecl foo::* )(void) const'
2> ..\src\main.cpp(37) : see declaration of 'Call'
ok ,通过添加以下内容简单修复(I though:P):
ok, easy fix (I though :P ) by adding this :
template <class C, void (C::*Function)() const>
void Call(C* instance)
{
(instance->*Function)();
}
但现在编译器完全混淆了。它看起来像他现在试图使用const函数为非成员函数和非const函数的const成员函数。
but now the compiler is completly confused (and me with it). it looks like he now tries to use the const function for the non-const member function and the non-const function for the const member function.
2>..\src\main.cpp(53): error C2440: 'specialization' : cannot convert from 'void (__cdecl foo::* )(void)' to 'void (__cdecl foo::* const )(void) const'
2> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
2>..\src\main.cpp(53): error C2973: 'Call' : invalid template argument 'void (__cdecl foo::* )(void)'
2> ..\src\main.cpp(43) : see declaration of 'Call'
2>..\src\main.cpp(53): error C2668: 'Call' : ambiguous call to overloaded function
2> ..\src\main.cpp(43): could be 'void Call<foo,void foo::MemberFunction(void)>(C *)'
2> with
2> [
2> C=foo
2> ]
2> ..\src\main.cpp(37): or 'void Call<foo,void foo::MemberFunction(void)>(C *)'
2> with
2> [
2> C=foo
2> ]
2> while trying to match the argument list '(foo *)'
2>..\src\main.cpp(54): error C2440: 'specialization' : cannot convert from 'void (__cdecl foo::* )(void) const' to 'void (__cdecl foo::* const )(void)'
2> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
2>..\src\main.cpp(54): error C2973: 'Call' : invalid template argument 'void (__cdecl foo::* )(void) const'
2> ..\src\main.cpp(37) : see declaration of 'Call'
2>..\src\main.cpp(54): error C2668: 'Call' : ambiguous call to overloaded function
2> ..\src\main.cpp(43): could be 'void Call<foo,void foo::ConstMemberFunction(void) const>(C *)'
2> with
2> [
2> C=foo
2> ]
2> ..\src\main.cpp(37): or 'void Call<foo,void foo::ConstMemberFunction(void) const>(C *)'
2> with
2> [
2> C=foo
2> ]
2> while trying to match the argument list '(foo *)'
如果我重命名第二个Call函数(与const),它一切正常,但我宁愿使用一个函数。
If I would rename the second Call function (with the const), it all works fine but I would rather use one function.
所以,任何人都可以指出我做错了,让这项工作吗?
So, can anybody point me towards what I'm doing wrong and how I can make this work ?
Thx!
推荐答案
通过从模板类型签名中删除函数指针,而不是依赖于重载来解决这个问题:
I think you might be able to address this by removing the function pointer from the template type signature and instead relying on overloading:
template <class C>
void Call(C* ptr, void (C::*function)()) {
(ptr->*function)();
}
template <class C>
void Call(C* ptr, void (C::*function)() const) {
(ptr->*function)();
}
现在使用正常的函数重载来选择应该调用两个函数。 const
成员函数指针将调用第二个版本,而非 const
函数将调用第一个版本。这也意味着您不需要明确地向模板函数提供任何类型信息;编译器可以在两个上下文中推导出 C
。
This now uses normal function overloading to select which of the two functions should be called. const
member function pointers will call down to the second version, while non-const
functions will call up to the first version. This also means that you don't need to explicitly provide any type information to the template function; the compiler can deduce C
in both contexts.
让我知道如果(1)
希望这有助于!
这篇关于非类型模板函数指针指向const成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!