2011-12-07 9 views
0

私は次のように特定のクラス内のさまざまなメンバ関数にアクセスするために使用できるメンバ関数への「汎用」のポインタを定義しようとは:mポインタ::バリアント

class Security{ 
    inline std::vector<double> member_function(const std::string &input_data_string){ return ... a vector<double>....;}; 
    }; 

I boost :: variantを使用することで、異なる戻り値の型だけでなく異なる型のパラメータにアクセスするために使用できるメンバ関数への汎用ポインタを定義しています。

そして、これは私が得ているエラーです

ptr_sec_fn=&Security::member_function; 

メンバ関数へのポインタを割り当てる

typedef boost::variant<std::string,double, std::vector<double>, std::vector<std::string>> (Security::*ptr_sec_fn)(boost::variant<std::string,double, std::vector<double>, std::vector<std::string>>); 

cannot convert from 'std::vector<_Ty> (__thiscall Security::*)(const std::string &)' to 'boost::variant<T0_,T1,T2,T3> (__thiscall Security::*)(boost::variant<T0_,T1,T2,T3>)' 
1>   with 
1>   [ 
1>    _Ty=double 
1>   ] 
1>   and 
1>   [ 
1>    T0_=std::string, 
1>    T1=double, 
1>    T2=std::vector<double>, 
1>    T3=std::vector<std::string> 
1>   ] 
1>   Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast 

あなたは私がやっている識別するのに役立つてもらえここで間違っている?どうもありがとうございます。

+1

代わりに 'boost :: function'や' std :: function'を使用することを考えましたか? – AJG85

+0

また、 'boost :: bind'と' boost :: phoenix :: bind'を見てください。 – Smash

答えて

0

これはこの方法では機能しません。誰かがベクトルからバリアント型への変換をしなければならず、あなたの関数はそれを行うことができません(ベクトルを返すので、それはすべて知っています)。そして、ポインタを作成するコードは、その場で関数を作成することはできません)。

一方、あなたのデザインをとにかく考え直すことをお勧めします。とにかくそのような汎用関数ポインタが必要なのはなぜですか?より具体的に指定することはできますか?優れたデザインは、明確な型を通して表示されます。なぜなら、型によって、どのようなドキュメントよりも必要なデータがより正確にプログラマに表示されるからです。

+0

私は毎回別のメンバ関数を呼び出すたびにポインタを再定義したくないので、関数はその戻り値の型を知っています。ptr_sec_fn =&(boost :: get > Security :: member_function)..これが有効な構文であるかどうかわからない場合はどうすれば変換を行うことができますか? ! –

0

Security::member_functionのタイプは、std::vector<Ty> (_thiscall Security::*)(const std::string &)です。これは、割り当てようとしているポインタのタイプとはまったく異なります。これは許可されていません。そのバリアントを受け取り、返すメンバ関数のみを、その型のメンバ関数ポインタに割り当てることができます。

この割り当てが機能する場合、メンバ関数ポインタを呼び出そうとしているコードはバリアントを関数に渡し、関数は文字列を期待しているので機能が壊れます。誰かが何らかの形で文字列を取得する必要があることを誰かが知るための十分な情報がどこにもありません。関数がベクトルを返すとき、誰かがそのベクトルをバリアントの構築に使う必要があることを知る必要があります。それはコールサイトで行う必要がありますが、コールサイトはベクターが返されていることさえ知りません。どのタイプが返されているかを知っているという事実は十分ではなく、コンパイラはそれを知る必要があります。タイプを知っているということは、まずキャッチオールタイプを使用すべきでないことを示しています。あなたはちょうど正しいタイプを使うべきです。

さまざまな種類の関数をオーバーロードすると、さまざまな型が返されますが、これらのオーバーロードを指す単一のメンバー関数ポインタを持つことはできません。これをやろうとすると、C++の型安全性が完全に無視されます。だから、あなたが望むことを行うための型安全な方法を考えなければならないでしょう。

あなたの目標はあなたがそれを行う方法を見つけるのを助けることですが、あなたが現在試みていることは決して動かないでしょう。