5

この例を考えてみましょう。

#include <iostream>
#include <string>
#include <vector>
#include <iterator>

int main()
{
    std::string sen = "abc def ghi jkl";
    std::istringstream iss(sen);

    std::vector<std::string>    // declaration in question
    vec(std::istream_iterator<std::string>(iss),
        std::istream_iterator<std::string>());

    std::copy(vec.begin(), vec.end(),
              std::ostream_iterator<std::string>(std::cout, "\n"));
}

コンパイラは、の呼び出し時にエラーをスローしますstd::copy

request for member 'begin' in 'vec', which is of non-class type...

私はこのようなエラーを回避することができます:

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番目の回避策が機能する理由も疑問に思います。

4

1 に答える 1

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

geordiは言う:

<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);
}

出力は42です。

于 2012-01-19T14:43:19.510 に答える