2012-03-05 2 views
4

제 질문의 제목이하는 일을 실제로 어떻게 수행했는지는 알지만 만족스럽고 이식 가능한 방식은 아닙니다. 좀 더 구체적으로 설명하겠습니다. 내 문제는이 코드는 레드햇에서 컴파일 및 마이크로 소프트 비주얼 스튜디오 C++ 2008과 Windows 7에서 잘 작동하지만 것입니다, 지금C++에서 mem_fun이 특정 오버로드 된 멤버 함수를 선택하도록 강요합니다.

#include <algorithm> 
#include <functional> 

class A { 
public: 
    int my_val() const { return _val; }; 
    int& my_val() { throw "Can't do this"; }; 
     // My class is actually derived from a super class which has both functions, but I don't want A to be able to access this second version 
private: 
    int _val; 
} 

std::vector<int> get_int_vector(const std::vector<A*>& a) { 
    std::vector<int> b; 
    b.reserve(a.size()); 
    transform(a.begin(), a.end(), inserter(b, b.end()), 
     std::mem_fun<int, const A>(&A::my_val)); 
    return b; 
} 

:

내 코드의 옷을 벗었 및 수정 된 버전입니다 mem_fun(static_cast<int (A::*)() const>(&A::my_val)) :이와 mem_fun() 전화를 교체 할 경우 리눅스에서

error: call of overloaded 'mem_fun(<unresolved overloaded function type>)' is ambiguous 
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h:713: note: candidates are: std::mem_fun_t<_Ret, _Tp> std::mem_fun(_Ret (_Tp::*)()) [with _Ret = int, _Tp = const A] 
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h:718: note:     std::const_mem_fun_t<_Ret, _Tp> std::mem_fun(_Ret (_Tp::*)()const) [with _Ret = int, _Tp = const A] 

가 컴파일하고 잘 작동 : 나는 다음과 같은 오류가 (버전 4.1.2 20080704), ++ g와 리눅스. 그러나 나는이 솔루션이 첫 번째 것보다 미적 감각이 떨어진다는 것을 안다. 내가 원하는 것을 할 수있는 또 다른 휴대용 방법이 있습니까? (아마도이 ​​작업을 수행하는 명백한 간단한 방법이 있습니다. 그 작업을 통해 큰 소란을 피우고 있습니다 ...)

감사합니다. -Manuel

답변

1

나는 당신에 대해 잘 모르겠지만, 나에게 더 기뻐할 것입니다.

template <typename S,typename T> 
inline std::const_mem_fun_t<S,T> const_mem_fun(S (T::*f)() const) 
{ 
    return std::const_mem_fun_t<S,T>(f); 
} 

과 같이 사용 : 자신의 함수를 정의

std::vector<int> get_int_vector(const std::vector<A*>& a) { 
    std::vector<int> b; 
    b.reserve(a.size()); 
    int& (A::*my_val)() const = &A::my_val; 
    transform(a.begin(), a.end(), inserter(b, b.end()), std::mem_fun(my_val)); 
    return b; 
} 
+1

나는이 점을 부스트 바인딩 (또는 std :: bind를 가지고 있다면)을 가져 오거나 루프를 사용하는 것이 더 낫다고 생각한다. – 111111

+0

@ 111111 : boost :: bind는 도움이되지 않습니다. 실제 문제는 여러 오버로드를 해결할 수있는 바인더에 표현식을 전달할 때 C++에 캐스트 이외의 구문이 없어 오버로드가 통과하고 싶었다. – PlasmaHH

+0

본, 고맙습니다. 내가 찾고 있었던 것 같아요. 단지 한 노트, 당신의 코드는 g ++로 컴파일되지만 MS Visual Studio에서는 "오류 C2914 : 'const_mem_fun': 함수 인수가 모호하기 때문에 템플릿 인수를 추론 할 수 없으므로"const_mem_fun (...)을 지정해야합니다. '. – MPortilheiro

0
typedef int (A::*MethodType)() const; 
const_mem_fun(MethodType(&A::my_val)); 

이가있다 :

std::vector<int> get_int_vector(const std::vector<A*>& a) { 
    std::vector<int> b; 
    b.reserve(a.size()); 
    transform(a.begin(), a.end(), inserter(b, b.end()), 
     const_mem_fun(&A::my_val)); 
    return b; 
} 

캐스트를 피하기 위해 또 다른 대안이 같은 것 생각.

+0

네, 그걸 가져 주셔서 감사합니다. 코드를 수정했습니다. – MPortilheiro