c ++在类中保存类模板化函数指针

时间:2015-05-20 18:38:27

标签: c++

我有一个小问题,我无法解决这个问题。 我有一个看起来像这样的函数:

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)'

我明白错误在说什么,但我不知道如何解决。当我指向函数的地址时,为什么它甚至关心返回类型?

祝你好运 尼罗

2 个答案:

答案 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;
};

WorldEditor

struct WorldEditor
{
    template <typename T>
    std::unique_ptr<Environment> CreateEnvironment(int& _j, bool _addToStatic = false)
    {
        return std::make_unique<Environment>();
    }
};

解决方案:映射对象的成员fn指针,然后稍后调用

(我将在答案中使用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

Live Demo

解决方案2:使用std :: bind和std :: function

也许我们在创建map条目时已经知道了成员函数调用的参数。将std::bindstd::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

Live Demo 2