2011-07-06 5 views
10

는 내가 How do I specify a pointer to an overloaded function? 자주 질문에 대한 답을 알고 : 할당 또는 캐스트에 하나, 그리고 다른 모든 C++ 튜토리얼이 같은 문자열 (static_cast를 제공하거나 수행) uppercases :알고리즘에서 기본 인수와 함께 오버로드 된 함수를 어떻게 사용합니까?

transform(in.begin(), in.end(), back_inserter(out), (int(*)(int)) std::toupper); 

또는 같은를 : 깔끔하게 std::toupper<cctype>의 과부하를 선택

int (*fp)(int) = std::toupper; 
transform(in.begin(), in.end(), back_inserter(out), fp); 

.

그러나 질문 : 어떻게 비슷한 방식으로 <locale> 과부하를 선택할 수 있습니까?

char (*fp2)(char, const std::locale&) = std::toupper; 
transform(in.begin(), in.end(), back_inserter(out), fp2); 
// error: too few arguments to function 

또는 더 실질적으로, 사람이 정수의 벡터에 문자열의 벡터를 변환하는 알고리즘에서 C++ (11) std::stoi를 사용하려고 고려 : stoi 두 개의 오버로드 (string/wstring)가 각각 복용 두 개의 추가 기본 인수.

나는이 모든 기본값을 explicitly bind으로하고 싶지 않다고 가정 할 때 보조 함수 나 람다에서 이러한 호출을 래핑하지 않으면이 작업을 수행 할 수 없다고 생각합니다. 완전히 일반적인 방식으로 나를 위해 그것을 할 수있는 부스트 래퍼 또는 TMP 마법 있나요? call_as<char(char)>(fp2) 또는 더 많은 경우 call_as<int(const std::string&)>(std::stoi)과 같은 래퍼를 쓸 수 있습니까?

+3

당신이 당신의'transform' 명령에서 람다를 사용할 수 있습니까? 가장 쉽고 깨끗합니다. –

+0

나는 이미 당신이 찾고 있던 래퍼 인'bind'에 대한 코멘트를 작성하고 삭제했습니다. 그런 다음 바인딩 할 기본값을 제공해야하므로 다시 정의해야합니다. –

+0

템플릿을 통해 코드를 난독 화하는 방법을 생각하기에 앞서 알고리즘을 직접 얻는 것이 좋습니다. 알고리즘으로 시작하십시오. 'std :: toupper' 호출은'EOF' 값을 제외하고는 음의 인수가 있으면 정의되지 않은 동작을 낳습니다. –

답변

5

재미 있습니다. 비슷한 것을했습니다. 내가 찾은 가장 좋은 방법은 lambdas를 다음과 같이 사용하는 것이 었습니다. 그렇지 않으면 typedef를 사용하여 올바른 오버로드와 std :: bind를 사용하여 로케일을 제거하거나 로캘을 사용하지 않아야했기 때문입니다. 그러나 이것은 훨씬 더 깨끗하게 작동합니다.

static const std::locale loc; 
transform(in.begin(), in.end(), back_inserter(out), [&loc](char c) { 
    return std::toupper(c, loc); 
}); 

매번 다시 할당하는 노력을 줄이기 위해 정적을 사용합니다.

또는 당신은 타입 정의를 얻을 수 및 수행

std::bind((LocaleCompare)std::toupper, std::placeholders::_1, loc); // UGLY! 
0

해당 functon 포인터 형식의 typedef를 만든 다음 함수를 캐스팅 할 수 있습니다.

typedef char (*LocaleToUpper)(char, const std::locale&) ; 
char (*fp2)(char, const std::locale&) = (LocaleToUpper)toupper; 
관련 문제