gpt4 book ai didi

c++ - 使用继承的成员函数指针的 unordered_map,使用 std :function

转载 作者:太空宇宙 更新时间:2023-11-04 13:19:17 25 4
gpt4 key购买 nike

我正在尝试创建和使用成员函数指针的 unordered_map 作为接口(interface)的一部分,它由子类继承和使用。最终目标是让子类可以被脚本使用(“脚本化”),这样它们的功能就可以被文本“命令”调用。

我在语法方面遇到了问题,并且在成员函数指针及其继承和使用方面遇到了困难。我尝试了很多变体,但正如我的谷歌搜索显示的那样,这是一个复杂而微妙的问题。

界面:

#include <string>
#include <vector>
#include <unordered_map>
#include <functional>

using namespace std;

class IScriptable
{
public:
virtual void Init() = 0;
bool Run_Script_Command(string i_Command, vector<string> i_Arguments);
protected:
void Register_Command_Function_Pair(string i_Command, function<void(const IScriptable&, vector<string>)> i_Function);

unordered_map<string, function<void (const IScriptable&, vector<string>)>> m_Command_Functions;
};

bool IScriptable::Run_Script_Command(string i_Command, vector<string> i_Arguments)
{
if (m_Command_Functions.find(i_Command) != m_Command_Functions.end())
{
(m_Command_Functions[i_Command])(*this, i_Arguments);
}
else
{
return(false);
}

return(true);
}

void IScriptable::Register_Command_Function_Pair(string i_Command, function<void(const IScriptable&, vector<string>)> i_Function)
{
m_Command_Functions[i_Command] = i_Function;
}

子对象:

class Child : public IScriptable
{
public:
virtual void Init();
protected:
void Foo(vector<string> parms); // The function I'm going to try and add and invoke later
};

void Child::Init()
{
Register_Command_Function_Pair("TestFunction", &Child::Foo);
}

void Child::Foo(vector<string> parms)
{
cout << "Calling Foo\n";
for (vector<string>::iterator it = parms.begin(); it != parms.end(); it++)
{
cout << *it;
cout << "\n";
}
}

代码使用示例:

int main()
{
Child c;
c.Init();

vector<string> arguments;
arguments.push_back("Testing");
arguments.push_back("123");
c.Run_Script_Command("TestFunction", arguments);

// Expected output:
// Calling Foo
// Testing
// 123
}

我已经尝试创建一个简化的示例来说明我正在尝试做的事情,所以希望我的目标是有意义的,即使存在一些其他糟糕的设计决策(为了示例而做出的)。

我怎样才能让它编译并给我预期的输出?

谢谢。

编辑:上面的代码应该抛出以下编译器错误:

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional(506): error C2664: 'void std::_Func_class<_Ret,const IScriptable &,std::vector<std::string,std::allocator<_Ty>>>::_Set(std::_Func_base<_Ret,const IScriptable &,std::vector<_Ty,std::allocator<_Ty>>> *)' : cannot convert argument 1 from '_Myimpl *' to 'std::_Func_base<_Ret,const IScriptable &,std::vector<std::string,std::allocator<_Ty>>> *'
with
[
_Ret=void
, _Ty=std::string
]
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional(442) : see reference to function template instantiation 'void std::_Func_class<_Ret,const IScriptable &,std::vector<std::string,std::allocator<_Ty>>>::_Do_alloc<_Myimpl,_Fret(__cdecl Child::* const &)(std::vector<_Ty,std::allocator<_Ty>>),_Alloc>(_Fty,_Alloc)' being compiled
with
[
_Ret=void
, _Ty=std::string
, _Fret=void
, _Alloc=std::allocator<std::_Func_class<void,const IScriptable &,std::vector<std::string,std::allocator<std::string>>>>
, _Fty=void (__cdecl Child::* const &)(std::vector<std::string,std::allocator<std::string>>)
]
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional(442) : see reference to function template instantiation 'void std::_Func_class<_Ret,const IScriptable &,std::vector<std::string,std::allocator<_Ty>>>::_Do_alloc<_Myimpl,_Fret(__cdecl Child::* const &)(std::vector<_Ty,std::allocator<_Ty>>),_Alloc>(_Fty,_Alloc)' being compiled
with
[
_Ret=void
, _Ty=std::string
, _Fret=void
, _Alloc=std::allocator<std::_Func_class<void,const IScriptable &,std::vector<std::string,std::allocator<std::string>>>>
, _Fty=void (__cdecl Child::* const &)(std::vector<std::string,std::allocator<std::string>>)
]
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional(442) : see reference to function template instantiation 'void std::_Func_class<_Ret,const IScriptable &,std::vector<std::string,std::allocator<_Ty>>>::_Reset_alloc<_Fret,Child,std::vector<_Ty,std::allocator<_Ty>>,std::allocator<std::_Func_class<_Ret,const IScriptable &,std::vector<_Ty,std::allocator<_Ty>>>>>(_Fret (__cdecl Child::* const )(std::vector<_Ty,std::allocator<_Ty>>),_Alloc)' being compiled
with
[
_Ret=void
, _Ty=std::string
, _Fret=void
, _Alloc=std::allocator<std::_Func_class<void,const IScriptable &,std::vector<std::string,std::allocator<std::string>>>>
]
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional(442) : see reference to function template instantiation 'void std::_Func_class<_Ret,const IScriptable &,std::vector<std::string,std::allocator<_Ty>>>::_Reset_alloc<_Fret,Child,std::vector<_Ty,std::allocator<_Ty>>,std::allocator<std::_Func_class<_Ret,const IScriptable &,std::vector<_Ty,std::allocator<_Ty>>>>>(_Fret (__cdecl Child::* const )(std::vector<_Ty,std::allocator<_Ty>>),_Alloc)' being compiled
with
[
_Ret=void
, _Ty=std::string
, _Fret=void
, _Alloc=std::allocator<std::_Func_class<void,const IScriptable &,std::vector<std::string,std::allocator<std::string>>>>
]
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,const IScriptable &,std::vector<std::string,std::allocator<_Ty>>>::_Reset<void,Child,std::vector<_Ty,std::allocator<_Ty>>>(_Fret (__cdecl Child::* const )(std::vector<_Ty,std::allocator<_Ty>>))' being compiled
with
[
_Ret=void
, _Ty=std::string
, _Fret=void
]
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,const IScriptable &,std::vector<std::string,std::allocator<_Ty>>>::_Reset<void,Child,std::vector<_Ty,std::allocator<_Ty>>>(_Fret (__cdecl Child::* const )(std::vector<_Ty,std::allocator<_Ty>>))' being compiled
with
[
_Ret=void
, _Ty=std::string
, _Fret=void
]
Source\GoDatabase.cpp(3436) : see reference to function template instantiation 'std::function<void (const IScriptable &,std::vector<std::string,std::allocator<_Ty>>)>::function<void(__cdecl Child::* )(std::vector<_Ty,std::allocator<_Ty>>)>(_Fx &&)' being compiled
with
[
_Ty=std::string
, _Fx=void (__cdecl Child::* )(std::vector<std::string,std::allocator<std::string>>)
]
Source\GoDatabase.cpp(3436) : see reference to function template instantiation 'std::function<void (const IScriptable &,std::vector<std::string,std::allocator<_Ty>>)>::function<void(__cdecl Child::* )(std::vector<_Ty,std::allocator<_Ty>>)>(_Fx &&)' being compiled
with
[
_Ty=std::string
, _Fx=void (__cdecl Child::* )(std::vector<std::string,std::allocator<std::string>>)
]

最佳答案

你的函数类型应该是:

std::function<void(std::vector<std::string>)>

const IScriptable& 在那里不起作用,如果你想使用指向方法的指针,那将是完全不同的语法。

那么 Init() 可能是这样的:

using namespace std::placeholders;
Register_Command_Function_Pair("TestFunction", std::bind( &Child::Foo, this, _1 ) );

Run_Script_Command() 变为:

bool IScriptable::Run_Script_Command(string i_Command, vector<string> i_Arguments)
{
auto f = m_Command_Functions.find(i_Command);
if ( f != m_Command_Functions.end())
{
f->second(i_Arguments);
return true;
}
return false;
}

请注意,您应该在使用时为正在使用的 std::function 创建类型别名(通过 typedefusing)多次。这将使代码更具可读性,并且更容易更改该类型。

关于c++ - 使用继承的成员函数指针的 unordered_map,使用 std :function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35923785/

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