2017-09-09 6 views
0

関数リダイレクトでifとhardcoded文字列を使用しないようにする方法がありますか?文字列を受け取り、テンプレート/メタプログラミングでapropiate関数を呼び出すことです。C + +ハードコードされた文字列を避ける場合

#include <string> 
#include <iostream> 

void account() 
{ 
    std::cout << "accout method" << std::endl; 
} 

void status() 
{ 
    std::cout << "status method" << std::endl; 
} 

void redirect(std::string method_to_call) 
{ 
    if(method_to_call == "account") 
    { 
     account(); 
    } 
    else if(method_to_call == "status") 
    { 
     status(); 
    } 
    else 
    { 
     std::cout << "method not found!!" << std::endl; 
    } 
} 

int main() 
{ 
    std::string method_name; 
    std::cin >> method_name; 

    redirect(method_name); 

    return 0; 
} 
+7

あなただけなし、 'のstd :: map'を使用することができますか? –

+3

* "多分テンプレート/メタプログラミング" * - テンプレートはコンパイル時の決定であり、関数の選択はユーザ入力に依存する実行時の決定であるため、最初からリストから外すことができます。 – WhozCraig

答えて

3

これを実現するにはstd :: mapとstd :: functionを使用できますが、挿入ポイントにはまだハードコーディングされた文字列が必要です。

void status() 
{ 
    std::cout << "status" << std::endl; 
} 

void account() 
{ 
    std::cout << "account" << std::endl; 
} 

int main() 
{ 
    std::map< std::string, std::function<void()> > functions; 

    functions.emplace("status" , status ); 
    functions.emplace("account", account); 

    std::string method_name; 
    std::cin >> method_name; 

    auto iter(functions.find(method_name)); 
    if(iter != functions.end()) 
    { 
     iter->second(); 
    } 
    else 
    { 
     std::cout << "Method " << method_name << " not found!!" << std::endl; 
    } 
} 

マクロを使用して喜んでいるなら、あなたはこのような余分な文字列を避けることができますが:

#define ADD_FUNCTION(map, func) map.emplace(#func, func); 

std::map< std::string, std::function< void() > > functions; 
ADD_FUNCTION(functions, status ); 
ADD_FUNCTION(functions, account); 
+3

C++ 11のイニシャライザリストを使用しないのはなぜですか? 'map <...> function = {{" status "、status}、{" account "、account}}' – myaut

+0

はきれいな解決策です。ありがとうございました – jsubi

関連する問題