2012-03-05 10 views
4

私の質問にはタイトルが何をするのかを実際には分かりましたが、満足のいく移植方法ではありません。私はもっ​​と具体的にしましょう。C++はmem_funに特定のオーバーロードされたメンバ関数を選択させるように強制します

これは私のコードのストリップダウンし、修正版である:、私の問題は、このコードはコンパイルして、マイクロソフトのVisual Studio C++ 2008でWindows 7で正常に動作していることですが、ないのRed Hatで今

#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()コールを交換する場合は、Linuxで

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)、++グラムしたLinux。しかし、私は、このソリューションが最初のものよりも審美的に魅力的ではないことを発見しました。私が欲しいことをするもう一つのポータブルな方法はありますか? (おそらく、これを行うための明らかな単純な方法があり、私はそれに大きな騒ぎをしています...)

ありがとうございます。 -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()); 
    transform(a.begin(), a.end(), inserter(b, b.end()), 
     const_mem_fun(&A::my_val)); 
    return b; 
} 

別の方法としては、このようなものになるだろう:

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:ブースト::バインドはここでは役に立ちません。真の問題は、複数のオーバーロードを解決できるバインダーに式を渡すと、C++にはキャスト以外の構文がないため、パスしたかった。 – PlasmaHH

+0

ヴォーンありがとう、私はこれが私が探していたものだと思います。あなたのコードはg ++でコンパイルされますが、 "エラーC2914: 'const_mem_fun':関数の引数があいまいなのでテンプレート引数を推論できません"というMS Visual Studioではなく、 'const_mem_fun (...) '。 – MPortilheiro

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

ですアイディア。

+0

はい、それを選んでいただきありがとうございます。私はコードを編集しました。 – MPortilheiro

関連する問題