2009-06-14 19 views
2

をブースト::関数オブジェクトを構築するとき、私は工assコンストラクタに引数の前後に括弧を挿入またはブーストを構築する場合は、以下のコードは、Visual C++ 2005エラーC2228コンストラクタ引数リストに

class SomeClass { 
public: boost::function<void()> func; 
     SomeClass(boost::function<void()> &func): func(func) { } 
}; 

void someFunc() { 
    std::cout << "someFunc" << std::endl; 
} 

int main() { 
    SomeClass sc(boost::function<void()>(&someFunc)); 
    sc.func(); // error C2228: left of '.func' must have class/struct/union 
    return 0; 
} 

にコンパイルされません。 :引数リストの外にある関数オブジェクト。コンパイルがうまくいきます。

SomeClass sc((boost::function<void()>(&someFunc))); 
    // or 
    boost::function<void()> f(&someFunc); 
    SomeClass sc(f); 

前のコードの問題点は何ですか?

答えて

1

関数の宣言で、boost:function <void()>を参照し、SomeClassを返します。次のルールを覚えることができます。これは他の多くの曖昧さ回避のケースにも当てはまります。これらのケースの説明は、C++標準のセクション8.2にあります。

おそらく宣言することができ、任意の構築物が宣言手段

として解釈され、以下では余分な括弧

boost::function<void()>(&someFunc) 

場合で、パラメータ宣言として取られますかっこを削除すると、これは明らかになります。

boost::function<void()> &someFunc 

こうして、全体の宣言はもう

SomeClass sc(boost::function<void()> &someFunc); 

キャスト表記

SomeClass sc((boost::function<void()>)&someFunc); 

を使用するかのように、式全体の周りに括弧をつけ、それを修正するために、オブジェクトが、関数を宣言しませんした。ここ

8.2からそのすべての栄光で標準である:

関数スタイルのキャストおよび6.8で述べた宣言との間の類似性に起因するあいまいさはまた、宣言のコンテキストで起こり得ます。このコンテキストでは、パラメータ名の周りの括弧の冗長なセットを持つ関数宣言と、初期化子としての関数形式のキャストを持つオブジェクト宣言の間の選択です。 6.8で言及されたあいまいさと同様に、解決策は、宣言である可能性のある構築物を宣言とみなすことです。 [注:宣言は、非関数形式のキャストによって明示的に曖昧さを取り除くことができます。初期化を示すためには、=を使用するか、パラメータ名の前後に括弧を入れてください。 ]の優先順位を制御するために、次の

int (((((((a))))))) = 3; 
int (*(pa)) = &a; 
でのように、ちょうど約どこでも括弧を紹介して許可されていることを

注意

関連する問題