2012-09-21 5 views
7

メンバ関数に暗黙のthisポインタパラメータがあります。 std::functionがこの署名を受け入れるのはなぜですか?Sは単純なクラスですか? (complete sampleなぜstd ::関数は署名内でこの参照を受け入れますか?

std::function<void(S &)> func = &S::foo; 

も動作し、オブジェクトを区別し、それを呼び出す:

S s1 = {5}; 
S s2 = {6}; 

func(s1); //prints 5 
func(s2); //prints 6 

私が正常に期待することは、それは同様に動作ポインタを、必要とすることである:(complete sample

std::function<void(S * const)> func = &S::foo; 

S s1 = {5}; 
S s2 = {6}; 

func(&s1); //prints 5 
func(&s2); //prints 6 

なぜ暗黙のthisパラメーターがポインターである場合に、メンバー関数に参照を渡すと、最初のものが機能しますか?

答えて

3

std::function<SIG>は、関数のように動作する多くのものか​​ら構築し、適切なstd::functionオブジェクトに変換することができます。 (どちらも何も返さない、呼び出し、および潜在的にSを変更するSを必要とするように)この場合void S::foo()

は多くの機能void foo_x(S&)のように振る舞います。その結果、std::function<void(S&)>は、メンバ関数を関数オブジェクトに変換するためのコンストラクタを提供します。私。

std::function<void(S * const)> func = &S::foo; 

void foo_x(S * const s) { return s->foo(); } 
std::function<void(S* const)> func = foo_x; 

に相当し、同様に

void foo_x(S & s) { return s.foo(); } 
std::function<void(S&)> func = foo_x; 

std::function<void(S &)> func = &S::foo; 

はと同等のものを作成するために、 std::function<void(S&)>(void(S::)())のように、何かをコンストラクタを使用していますコンストラクタ std::function<void(S* const)>(void(S::)())

+2

これは非常に有益な読書でした、ありがとうございました。 'std :: function'は生の関数ポインタとは独立していると考えて、それがラップしているものの使いやすさを増やすのが好きなことをする力を持っていると考えると、もっと意味があります。 – chris

5

std::functionが正しく設計されているためです。 thisがポインタであるという事実は、履歴の事故であり、メンバ関数の内部の詳細です。この事実は、その機能のユーザーの意思決定に影響を与えるべきではありません。

std::functionの設計者は、シグネチャの最初のパラメータ型が参照である場合にメンバー関数を受け入れることを決定しました。