2017-09-09 3 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

당신은 단지 아니,'표준 : :지도'를 사용할 수 있습니까? –

+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 이니셜 라이저 목록을 사용하지 않는 이유는 무엇입니까? '<...> function = {{ "status", status}, { "account", account}}' – myaut

+0

깨끗한 해결책입니다. 내 프로젝트에서 사용하겠습니다. 고맙습니다 – jsubi