2012-01-19 6 views
5

は、この例で考えてみましょう関数の宣言として解析されますこのように:ベクトルコンストラクタが

std::istream_iterator<std::string> it_begin(iss); 
std::istream_iterator<std::string> it_end; 
std::vector<std::string> vec(it_begin, it_end); 

またはこのような、各パラメータの周りに括弧を置くことによって:

std::vector<std::string> 
vec((std::istream_iterator<std::string>(iss)), 
    (std::istream_iterator<std::string>())); 

あるいはC++ 11に新しい均一な初期化となぜコンパイラは、一例としてで宣言を構文解析さ

std::vector<std::string> vec { /*begin*/, /*end*/ }; 

関数宣言?私は最も厄介な解析について知っていますが、私は空のパラメータリストでしか起こらないと思っていました。 2番目の回避策がなぜ機能するのだろうか。

+0

GCC 4.6.1(重要な場合)私もcomauのオンラインコンパイラで試してみました。 – jrok

+0

次のように入力しないでください: 'std :: istream_iterator it_begin(iss)、it_end; std :: vector vec(it_begin、it_end); ' –

+0

よく構成され、整形式でよくフォーマットされた質問です。よくやった。 :) –

答えて

9

これはまだ最も厄介な解析です。

std::vector<std::string>      // return type 
vec(          // function name 
    std::istream_iterator<std::string>(iss), // param 1: an iterator called (iss), or just iss 
    std::istream_iterator<std::string>()  // param 2: unnamed function 
);           //   returning iterator 

ジョーディは言う:

<tomalak> << ETYPE_DESC(vec); std::vector<std::string> vec(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>()); 
<geordi> lvalue function taking a istream_iterator<string, char, char_traits<char>, long> , a pointer to a nullary function returning a istream_iterator<string, char, char_traits<char>, long> , and returning a vector of strings 

それの核心、本当に、あなたのパラメータ名は、宣言の意味を変えることなく、彼らの周りの括弧(すなわちiss(iss))を持つことができるということです。時々。

示したように、タイプを囲む別の括弧を使用して、最初のパラメータ(したがって、2番目のパラメータ)を宣言ではなく式として解析するようにします。それが助け場合


、も検討してください:

void foo(int (x)) { 
    cout << x; 
} 

int main() { 
    foo(42); 
} 

Output is 42を。

+0

@Als:宣言は完全に有効です。しかし、それはベクトル宣言と関数宣言の両方として有効であり、標準は後者が優先されると述べています。それはあなたの基本的なものです(http://en.wikipedia.org/wiki/Most_vexing_parse)。 OPは、最初の引数の名前の周りの括弧のために、宣言が有効な_function_宣言であることに単純に驚いています。 –

+0

Err..おそらく、それらの括弧は冗長であり、とにかくそれらの括弧のn個を置くことができ、それは同じように動作します。 –

+0

@Als:そうです。それがポイントです。複数形は "かっこ"です。 –