gpt4 book ai didi

c++ - 指向 const 成员函数的非类型模板函数指针

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:55:58 25 4
gpt4 key购买 nike

我正在编写一个委托(delegate)类,但它无法采用 const 成员函数。这是一个测试用例:

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 函数:

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'

好吧,通过添加这个很容易修复(我虽然 :P ):

template <class C, void (C::*Function)() const>
void Call(C* instance)
{
(instance->*Function)();
}

但现在编译器完全糊涂了(我也糊涂了)。看起来他现在尝试对非常量成员函数使用 const 函数,对 const 成员函数使用非常量函数。

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),一切正常,但我宁愿使用一个函数。

那么,任何人都可以指出我做错了什么以及我如何才能做到这一点吗?

谢谢!

最佳答案

我认为您可以通过从模板类型签名中删除函数指针并改为依赖重载来解决此问题:

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

如果 (1) 这不起作用或 (2) 这确实有效,但不是您想要的,请告诉我。

希望这对您有所帮助!

关于c++ - 指向 const 成员函数的非类型模板函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11090109/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com