如何将方法存储为地图容器中的函数指针?

Rin*_*ro. 17 c++ pointers function

我希望能够根据从文件中读取的数据调用函数.因此,对于每种项目类型,我想调用所需的读者方法.我编写了这段代码,但它没有编译我想在地图中添加函数指针的地方.怎么了?

#include <vector>
#include <map>
#include <iostream>
class reader
{

  std::map< std::string, void(*)()> functionCallMap; // function pointer
  void readA(){ std::cout << "reading A\n";};
  void readB(){ std::cout << "reading B\n";};;
public:
  reader()
  {
    *functionCallMap["A"] = &reader::readA;*
    *functionCallMap["B"] = &reader::readB;*
  }

  void read()
  {
   auto (*f) = functionCallMap["A"];
   (*f)();
  }



};
Run Code Online (Sandbox Code Playgroud)

我在Constructor填写地图.

小智 20

您可以使用std::functionlambda或std::bind:

class reader
{
    std::map<std::string, std::function<void()>> functionCallMap;

    void readA() { std::cout << "reading A\n"; };
    void readB() { std::cout << "reading B\n"; };

public:
    reader()
    {
        functionCallMap["A"] = [this]() { readA(); };
        functionCallMap["B"] = std::bind(&reader::readB, this);
    }

    void read()
    {
        functionCallMap["A"]();
        functionCallMap["B"]();
    }
};
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢你的解决方案,因为它比原始函数指针更 C++ 且更干净。无论如何,lba 应该优先于 std::bind (Scott Meyer 的有效现代 C++) (2认同)
  • 是的,这是一个很好的解决方案。但是,根据 Jason Turner 的说法,bind 在编译时间和内存使用方面都很昂贵。 (2认同)

sna*_*yle 17

您需要使用指向成员函数的指针,如下所示:

class reader
{
    using FuncPtr = void(reader::*)(); // function pointer
    std::map< std::string, FuncPtr> functionCallMap;
    void readA(){ std::cout << "reading A\n"; }
    void readB(){ std::cout << "reading B\n"; }
public:
    reader()
    {
        functionCallMap["A"] = &reader::readA;
        functionCallMap["B"] = &reader::readB;
    }

    void read()
    {
        auto f = functionCallMap["A"];
        (this->*f)();
    }
};

int main()
{
    reader r;
    r.read();
}
Run Code Online (Sandbox Code Playgroud)


Han*_*999 9

到目前为止,有两个答案,这个这个.

明显的区别是一个使用std::function和其他使用函数指针.这不是重要的区别!!

关键是成员函数是非静态成员函数.所以,它们属于类型void().

它们属于类型void(reader::*)().因此,只有给出类型的对象是读者才可以调用它们; 人们可以将其理解为隐藏参数.

一个答案只是通过指定正确的类型来解决问题.这可以使用函数指针(如所示)使用std::function(后者更昂贵!)来完成.

第二个答案通过解决问题结合函数指针类的特定实例.绑定后,确实是类型void().这不能使用原始函数指针来完成(因为它们只能指向函数而不是对象/函数对!).