2016-12-25 9 views
-1
void foo(); 
class Foomatic() { 
    void bar(); 
    void baz() 
    { 
     std::thread a(foo); // this compiles 
     std::thread b(Foomatic::bar, this); // this doesn't 
     std::thread c(&Foomatic::bar, this); // and this compiles 
     // ... 
    } 
}; 

私は、メンバー関数へのポインタの正しい構文が&Foomatic::barであることを知っています。メンバー関数へのポインタ - 構文

しかし、なぜ正確にFoomatic::barが間違っていますか?それは何を返しますか?そして、なぜ正確に&Foomatic::barが正しいのでしょうか?私にとっては直感に反するようです。

これは重複していません。あなたがリンクした質問は正しい構文が何であるか、なぜその理由が説明されたのかを答えます。

私はC++がここで矛盾しているのはなぜか、私はすでに構文が何であるかを知っています。 (あなたがアドレス演算子&を使用して、関数のアドレスを取っているため)

+0

@Edヒール:これは重複していません。私はそれが何であるかを知っているので正しい構文が何であるかを尋ねていますが、**正しい構文が正しい理由は何ですか。答えは、正しい構文が何であるかだけを示します。 – marmistrz

+3

答えは同義語です。言語仕様がそうであるため、構文は正しくありません。なぜサッカーの試合は90分かかるのですか?それがルールが言うことだからです。 –

+3

おそらく本当の質問は 'a(&foo)'だったはずの 'a(foo)'が動作する理由です。 –

答えて

4

C++はCからの関数ポインタから関数ポインタへの変換を継承しました。Cでは、アドレスを取る必要なく関数ポインタに関数名を代入するだけでした。関数名への関数ポインタの "崩壊"は幾分不公平で、Cで混乱の原因となっていました。

導入されたメンバへのポインタがC:メンバーに。したがって、メンバ名からメンバへのポインタへの暗黙的な変換を行わないという選択肢がありました。ファシリティは、後で必要になるが、ほとんど削除されないと考えられる場合に後で追加できるので、メンバー名からメンバへのポインタへの暗黙的な変換を行わないという選択が行われました。

関数へのポインタ、メンバーへのポインタ、およびオブジェクトへのポインタを取得するための合理的に一貫したインタフェースがあるため、メンバ名からメンバへのポインタへの暗黙的な変換は必要ありませんオブジェクト名からオブジェクトへのポインタへの暗黙的な変換はありません。

意味的には、T::memberのようなものは、メンバへのポインタではなくメンバへの参照です。しかし、私は現在の仕様でこの型を定式化することは可能ではないと思います。可能であれば、将来の標準でこの構文のsometingを定義します。

0

&Foomatic::Bar場合へのポインタメンバー関数であり、その後、Foomatic::Barメンバ関数ではなく、ポインタへ-member関数。

これは、メンバー以外の関数とまったく同じです。&fooが(非メンバー)関数へのポインターである場合、fooは関数です。

C++もCもファーストクラスのオブジェクトとしては機能しません。たとえば、型/値が関数である変数を持つことはできません。非メンバ関数のシンタックスシュガー特別な場合として

は、あなたがfoo(42)は(非会員)へのポインタである(*foo)(42)foo場合のための短い手で、例えば、最初に明示的にそれを欽慕することなく、機能を言わ呼び出すことができます関数。

関連する問題