3
auto queue = [](string str) {
    istringstream ss(str);
    //std::copy(std::istream_iterator<string>(ss),
    //          std::istream_iterator<string>(),
    //          std::ostream_iterator<string>(std::cout, " "));

    //deque<string> q(std::istream_iterator<string>(ss), std::istream_iterator<string>{});
    deque<string> q(std::istream_iterator<string>(ss), std::istream_iterator<string>());
    return q;
};

Why would the compiler complain

parentheses were disambiguated as a function declaration [-Wvexing-parse]

if I construct a container with istream_iterator<string>().

Is there any difference with parameters in std::copy and container constructor?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
isudfv
  • 179
  • 1
  • 9
  • 3
    https://en.wikipedia.org/wiki/Most_vexing_parse – frippe Mar 28 '22 at 11:42
  • 2
    `q` is a function that takes two arguments; an iterator "ss", and an unnamed function taking no arguments and returning an iterator. It returns a `deque`. – molbdnilo Mar 28 '22 at 11:46
  • 1
    `std::istream_iterator()` *can* be an unnamed parameter in a function declaration. And if it can, `q` must be treated as a function. If you have `{}` or `" "`, those are obvious values, so cannot be part of a function declaration. – BoP Mar 28 '22 at 11:47

1 Answers1

5

This line

 deque<string> q(std::istream_iterator<string>(ss),
                 std::istream_iterator<string>());

is a function declaration with the return type deque<string> and two parameters of the type std::istream_iterator<string>. The first parameter has the name ss and the second parameter is unnamed.

To make this line a declaration of the variable q you should write either

 deque<string> q( ( std::istream_iterator<string>(ss) ),
                  (  std::istream_iterator<string>() ) );

or

 deque<string> q(std::istream_iterator<string>{ ss },
                 std::istream_iterator<string>{});

In this case there are used expressions instead of parameter declarations.

You may include declarators in parentheses. For example

int ( x );

When a declaration is a parameter declaration then you may omit a declarator like

int()

Here is an example of three declarations of the same function.

int f( int( x ) );
int f( int x );
int f( int( x ) )
{
    return 2 * x;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Why not go even further and replace *all* constructor call parenthesis with braces? I like me some consistency, and it avoids all variants of the Most Vexing Parse. – DevSolar Mar 28 '22 at 11:56
  • @DevSolar - It instead gets you into the *almost* uniform initialization, where `vector v(1, 2);` and `vector v{1, 2};` creates different sized vectors. :-( – BoP Mar 28 '22 at 12:01
  • The second parameter is parameterless and unnamed function of no arguments. – molbdnilo Mar 28 '22 at 12:14