Topic: No it really IS weird (see corrected code posted here)


Author: Dietmar Kuehl <dietmar.kuehl@claas-solutions.de>
Date: 1999/11/03
Raw View
Hi,
In article <B43CF834.748A%darin@bentspoon.com>,
  Darin Adler <darin@bentspoon.com> wrote:
> This is a classic problem with C++ syntax.

Well, it is not that classic as it surfaced only relatively recently
with wider use of STL and implementations supporting member templates
becoming available...

>     std::vector<int> v1(std::istream_iterator<int>(ss),
>         std::istream_iterator<int>());
>
> declares a function named v1 that returns a std::vector<int>, has a
first
> parameter of type std::istream_iterator<int> named ss, and a second
> parameter of type std::istream_iterator<int>.

Basically this is correct except that the type of the second parameter
is actually a function taking no arguments and returning an object of
type 'std::istream_iterator<int>'.
--
<mailto:dietmar.kuehl@claas-solutions.de>
homepage: <http://www.informatik.uni-konstanz.de/~kuehl>


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Marco Dalla Gasperina" <marcodg@pacifier.com>
Date: 1999/10/30
Raw View
Valentin Bonnard <Bonnard.V@wanadoo.fr> wrote in message
news:38172B96.785C@wanadoo.fr...
> Jeet Sukumaran wrote:
>
> > int main(void)
> > {
> >     std::stringstream ss("1 2 3 4 5 6 7 8 9 10");
> >     std::vector<int> v1(std::istream_iterator<int>(ss),
> >                         std::istream_iterator<int>());
> >
> >     v1.push_back(11);
> >     // error: "Structure required on left side of . or ."
>
> I see. v1 is a function taking a std::istream_iterator<int>
> and a (pointer to) function taking no arguments and
> returning a std::istream_iterator<int> and returning a
> std::vector<int>. Use an C-style cast, a new-style cast,
> but not a functional-style cast:
>
> std::vector<int> v1((std::istream_iterator<int>) ss,
>                     std::istream_iterator<int> ());
>
> or
>
> std::vector<int> v1(static_cast<std::istream_iterator<int> > (ss),
>                     std::istream_iterator<int> ());
>
> (And if you were wondering: yes, it _is_ ugly.)

Or, at the risk of being readable :-)

std::stringstream ss("1 2 3 4 5 6 7 8 9 10");

std::istream_iterator<int> ss_start(ss);
std::istream_iterator<int> ss_finish;
std::vector<int> v1( ss_start, ss_finish);

v1.push_back(11);

marco
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jeet Sukumaran <jeet_sukumaran@my-deja.com>
Date: 1999/10/27
Raw View
Hello Valentin.

Yes, I see the problems with the code as posted previously.  I really
must apologize to you and other readers though, for having posted
flawed code.  I was away from my own machine, and sort off created a
stripped-down version of the code on the fly.  Here is a much better
code example (provided in full to preclude the previous situation):

#include <sstream>
#include <vector>
#include <iterator>

int main(void)
{
    std::stringstream ss("1 2 3 4 5 6 7 8 9 10");
    std::vector<int> v1(std::istream_iterator<int>(ss),
                        std::istream_iterator<int>());

    v1.push_back(11);
    // error: "Structure required on left side of . or ."

    std::istream_iterator<int> begin(ss);
    std::istream_iterator<int> end;
    std::vector<int> v2(begin, end);

    v2.push_back(11);
    // no problems


    return 0;
}

As can be seen, the declaration and initialization syntax for v1 is
correct, but v1, for some mysterious reason, is not in the scope of the
function (in this case, main()): the compiler inevitable flags the
indicated line as an error.  The error message here is from Borland,
but gcc gives me an error that in essence means the same thing -- "I
don't know what the #%$#$%$ v1 is."

The second chunk, dealing with v2, is happily accepted by both
compilers.

Any ideas?

-- jeet


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/10/28
Raw View
Jeet Sukumaran wrote:

> int main(void)
> {
>     std::stringstream ss("1 2 3 4 5 6 7 8 9 10");
>     std::vector<int> v1(std::istream_iterator<int>(ss),
>                         std::istream_iterator<int>());
>
>     v1.push_back(11);
>     // error: "Structure required on left side of . or ."

I see. v1 is a function taking a std::istream_iterator<int>
and a (pointer to) function taking no arguments and
returning a std::istream_iterator<int> and returning a
std::vector<int>. Use an C-style cast, a new-style cast,
but not a functional-style cast:

std::vector<int> v1((std::istream_iterator<int>) ss,
                    std::istream_iterator<int> ());

or

std::vector<int> v1(static_cast<std::istream_iterator<int> > (ss),
                    std::istream_iterator<int> ());

(And if you were wondering: yes, it _is_ ugly.)

--

Valentin Bonnard
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/10/28
Raw View
Jeet Sukumaran <jeet_sukumaran@my-deja.com> writes:
>     std::vector<int> v1(std::istream_iterator<int>(ss),
>                         std::istream_iterator<int>());
>
>     v1.push_back(11);
>     // error: "Structure required on left side of . or ."

Isn't C++ annoying? You haven't declared v1 to be what you want.
Instead, you have declared that v1 is a *function* returning a
std::vector<int>, with two parameters. The first is of type
std::istream_iterator<int> and is named ss. The second is an
anonymous function taking no parameters and returning a
std::istream_iterator<int>. This second parameter is turned into
a function pointer by the language rules.

You can fix it with parentheses:

std::vector<int> v1((std::istream_iterator<int>(ss)),
                    (std::istream_iterator<int>()));

C and C++ declaration syntax is an abomination.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1999/10/28
Raw View
Jeet Sukumaran wrote in message <7v6t16$rmg$1@nnrp1.deja.com>...
>    std::vector<int> v1(std::istream_iterator<int>(ss),
>                        std::istream_iterator<int>());
> [ doesn't seem to define a vector named v1]

The lines above declare a function that takes two arguments.

If T1 and T2 are types and x1 and x2 are non-type identifiers then

  T1 x1(T2(x2), T2());             // Declares a function.  The parens
around x2 are optional
  T1 x1 = T1(T2(x2), T2());    // Defines a variable
  T1 x1((T2(x2)), T2());          // Defines a variable
  T1 x1(static_cast<T2>(x2), T2());    // Defines a variable.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Darin Adler <darin@bentspoon.com>
Date: 1999/10/28
Raw View
Jeet Sukumaran <jeet_sukumaran@my-deja.com> wrote:

> As can be seen, the declaration and initialization syntax for v1 is
> correct, but v1, for some mysterious reason, is not in the scope of the
> function (in this case, main()): the compiler inevitable flags the
> indicated line as an error.  The error message here is from Borland,
> but gcc gives me an error that in essence means the same thing -- "I
> don't know what the #%$#$%$ v1 is."

This is a classic problem with C++ syntax. This line

    std::vector<int> v1(std::istream_iterator<int>(ss),
        std::istream_iterator<int>());

declares a function named v1 that returns a std::vector<int>, has a first
parameter of type std::istream_iterator<int> named ss, and a second
parameter of type std::istream_iterator<int>.

You wanted to define a std::vector<int> object rather than declare a
function.

There are many ways to avoid the problem -- basically anything that makes it
not look to the compiler like a function declaration. One example is

    std::vector<int> v1((std::istream_iterator<int>(ss)),
        std::istream_iterator<int>);

where the parentheses do the trick.

    -- Darin
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Gabor Greif" <gabor@no.netopia.com>
Date: 1999/10/28
Raw View
On Wed, Oct 27, 1999 18:19 Uhr, Jeet Sukumaran
<mailto:jeet_sukumaran@my-deja.com> wrote:
>#include <sstream>
>#include <vector>
>#include <iterator>
>
>int main(void)
>{
>    std::stringstream ss("1 2 3 4 5 6 7 8 9 10");
>    std::vector<int> v1(std::istream_iterator<int>(ss),
>                        std::istream_iterator<int>());
>
>    v1.push_back(11);
>    // error: "Structure required on left side of . or ."
>
>    std::istream_iterator<int> begin(ss);
>    std::istream_iterator<int> end;
>    std::vector<int> v2(begin, end);
>
>    v2.push_back(11);
>    // no problems
>
>
>    return 0;
>}
>
>As can be seen, the declaration and initialization syntax for v1 is
>correct, but v1, for some mysterious reason, is not in the scope of the
>function (in this case, main()): the compiler inevitable flags the
>indicated line as an error.  The error message here is from Borland,
>but gcc gives me an error that in essence means the same thing -- "I
>don't know what the #%$#$%$ v1 is."
>
>The second chunk, dealing with v2, is happily accepted by both
>compilers.
>
>Any ideas?
>

Yes. I might be wrong but the thing you believe to be a _definition_ of v1
as a std::vector<int> constructed locally of two
std::istream_iterator<int>s is really a declaration of a function called v1
returning a std::vector<int> and taking two arguments.

I have been bitten by this weirdness several times. the workaround is to
write:

>    std::vector<int> v1(static_cast< std::istream_iterator<int> >(ss),
>                        std::istream_iterator<int>());

Hope this helps,

 Gabor
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]