我有一个小问题,我无法解决这个问题。 我有一个看起来像这样的函数:
template <typename T>
std::unique_ptr<Environment>& CreateEnvironment(sf::Vector2f& _position, bool _addToStatic = false);
这是我的函数指针typedef
typedef std::unique_ptr<Environment>& (WorldEditor::*CreateEnvironmentPtr)(sf::Vector2f&, bool);
std::map<std::string,CreateEnvironmentPtr> listEnv;
我试图简单地这样做:
listEnv["test"] = &CreateEnvironment<Coin>(sf::Vector2f(200,200), false);
我收到以下错误:
error C2440: '=' : cannot convert from 'std::unique_ptr<_Ty> *' to 'std::unique_ptr<_Ty> &(__thiscall WorldEditor::* )(sf::Vector2f &,bool)'
我明白错误在说什么,但我不知道如何解决。当我指向函数的地址时,为什么它甚至关心返回类型?
祝你好运 尼罗
答案 0 :(得分:2)
std::function
可以更好地解决这些问题
std::map<std::string, std::function<void()> listEnv;
listEnv.emplace("test", [] {
CreateEnvironment<Coin>(sf::Vector2f(200,200), false);
});
致电:
listEnv.at("test")->second();
答案 1 :(得分:2)
根据你的帖子,我不确定你是否正在尝试创建成员函数指针并映射到CreateEnvironment
类或其外部,所以我将解决我认为更难的问题指向单独对象的成员函数的指针。
我简化了你的课程:
struct Environment
{
int i = 1;
};
struct Coin
{
int k = 0;
};
struct WorldEditor
{
template <typename T>
std::unique_ptr<Environment> CreateEnvironment(int& _j, bool _addToStatic = false)
{
return std::make_unique<Environment>();
}
};
(我将在答案中使用C ++ 11/14语法)
//declare a pointer to member function in WorldEditor
using CreateEnvironmentPtr = std::unique_ptr<Environment> (WorldEditor::*)(int&, bool);
//declare an object of type WorldEditor, because member function pointers need a "this" pointer
WorldEditor myWorldEditor;
int myInt = 42;
//map a string to the CreateEnvironment<Coin> function
std::map<std::string, CreateEnvironmentPtr> listEnv;
listEnv["test"] = &WorldEditor::CreateEnvironment<Coin>;
// call the member function pointer using the instance I created, as well as
// the mapped function
(myWorldEditor.*listEnv["test"])(myInt, false);
// (printing member value to cout to show it worked)
std::cout << (myWorldEditor.*listEnv["test"])(myInt, false)->i << std::endl; // prints 1
也许我们在创建map条目时已经知道了成员函数调用的参数。将std::bind
与std::function
一起使用将有助于我们实现这一目标(与Richard Hodges'solution类似):
// now our "function pointer" is really just a std::function that takes no arguments
using CreateEnvironmentPtr = std::function<std::unique_ptr<Environment>(void)>;
//declare an object of type WorldEditor, because member function pointers need a "this" pointer
WorldEditor myWorldEditor;
int myInt = 42;
//map a string to that function pointer
//ensure it gets called with the right args
// by using std::bind (which will also make the arg list appear the be void at call time)
// note that std::bind needs an instance of the class immediately after
// listing the function it should be binding
// only afterwards will we then pass the int& and bool
std::map<std::string, CreateEnvironmentPtr> listEnv;
listEnv["test"] = std::bind(&WorldEditor::CreateEnvironment<Coin>, &myWorldEditor, myInt, false);
// the mapped function
listEnv["test"]()->i;
// (printing resulting unique_ptr<Environment>'s member to cout to show it worked)
std::cout << listEnv["test"]()->i << std::endl; // prints 1