2017-08-13 15 views
0

私はC++ 11の新機能ですので、今日はstd::functionで実験しています。クラスポインタに文字列のハッシュテーブルを作成するために使用しようとしています。小さなアセンブラのために私が作成しています:C++ - クラスメソッド関数ポインタのunordered_mapの初期設定リスト

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を初期化するにはどうすればよいですか?

+0

'assemble_data_processing'を静的メンバー関数にしようとしましたか? – Frank

答えて

1

あなたは

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);}} 
}; 

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

またはラムダを使用するか、またはあなたの関数は、静的にすることができます。

0

std::functionは、バインドされていないメンバ関数を保持することはできません。

状況に応じて、これを解決するには3つの方法があります。

a)assemble_data_processingにメンバーデータが使用されていない場合は、それを静的メンバー関数にして1日とします。

b)にあなたのキャッシュはと似たような使用して、その後、std::bindを使用して機能を結合し、単一Assemblerインスタンスに関連付けられている場合:Assemblerインスタンスは、その後、後で決定します何かあれば

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

c)をあなたはstd::functionを捨てて、古い関数ポインタをメンバ関数に使う必要があります。

+0

オリジナルのソースコードを誤解していると思います。私は後で 'Assembler'オブジェクトをインスタンス化します。 'assemble_data_processing'命令はprivateであることが意図されていましたが、メンバ関数を使用していなかったので、静的関数である可能性があります。上記の12月に提案されたラムダ式は、この問題を解決するようです。 – Nubcake

関連する問題