C ++ - 类方法函数指针的unordered_map的初始化列表

时间:2017-08-13 18:38:43

标签: c++ c++11 g++

我是C ++ 11的新手,所以我今天一直在尝试使用std::function,我试图用它来创建一个哈希表,用于字符串到类函数指针的小汇编我正在创建:

assemble.cpp

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

class Assembler {

    public:

    // Assembles the source file and writes it
    bool assemble(std::string output_file);

    // Creates the symbol table from a (.s) file
    bool create_symbol_table(std::string file_name);

    private:

    // Hash table for opcode to functions
    std::unordered_map<std::string,std::function<bool(std::vector<std::string>)>> 
    opcode_map =
    {
     {"add",assemble_data_processing}
    };

    bool assemble_data_processing(std::vector<std::string> instruction);

};

bool Assembler::assemble_data_processing(std::vector<std::string> instruction) {
    std::cout << "Data Processing" << std::endl;    
    return false;
}

这给了我g ++的编译时错误:

g++ -Wall -g -Werror -std=c++11 -o assemble.o assemble.cpp

assemble.cpp:28:5: error: could not convert ‘{{"add", ((Assembler*)this)->Assembler::assemble_data_processing}}’ from ‘<brace-enclosed initializer list>’ to ‘std::unordered_map<std::__cxx11::basic_string<char>, std::function<bool(std::vector<std::__cxx11::basic_string<char> >)> >’ }; ^

但是如果使函数成为非类函数,那么它编译时没有问题:

bool assemble_data_processing(std::vector<std::string> instruction) {
    std::cout << "Data Processing" << std::endl;    
    return false;
}

如何在类方法的大括号初始化列表中初始化unordered_map

2 个答案:

答案 0 :(得分:1)

您可以使用std::bind

std::unordered_map<std::string,std::function<bool(std::vector<std::string>)>> 
opcode_map =
{
 {"add", std::bind(&Assembler::assemble_data_processing, this, std::placeholders::_1}
};

或lambda

std::unordered_map<std::string,std::function<bool(std::vector<std::string>)>> 
opcode_map =
{
 {"add", [this](std::vector<std::string> instruction){return assemble_data_processing(instruction);}}
};

或者让你的功能保持静止。

答案 1 :(得分:0)

std::function无法保存非约束成员函数。

根据具体情况,您有三种方法可以解决这个问题。

a)如果assemble_data_processing不使用任何成员数据,请将其设为静态成员函数,并将其称为一天。

b)如果您的缓存与单个Assembler实例相关联,则使用类似于以下内容的std::bind绑定该函数:

opcode_map =
{
 {"add",std::bind(&Assembler::assemble_data_processing, this, _1)}
};

c)如果Assembler实例是稍后确定的,那么你将不得不抛弃std::function,并使用一个旧的函数指针来指向成员函数。