G++ takes code, Comeau barfs with "error: qualified name is notallowed"

R

red floyd

As far as I can tell, this code should be correct. G++ likes it, but
Comeau online hates it.

Errors [redacted] from Comeau online:
ComeauTest.c(47): error: qualified name is not allowed
std::vector<line_t> v(std::istream_iterator<line_t>
(std::cin),
^

ComeauTest.c(49): error: expression must have class type
std::sort(v.begin(), v.end());
^

ComeauTest.c(49): error: expression must have class type
std::sort(v.begin(), v.end());
^
[large numbers of STL errors redacted]

-----------------------
#include <iostream>
#include <ostream>
#include <istream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>


class line_t
{
private:
std::string s;
public:
friend std::istream& operator>>(std::istream& is, line_t& l)
{
return std::getline(is, l.s);
}

friend std::eek:stream& operator<<(std::eek:stream& os, const line_t& l)
{
return os << l.s;
}
const std::string& get_string() const
{
return s;
}
friend bool operator<(const line_t& l, const line_t& r)
{
std::string::size_type pos = l.get_string().find_last_of('/');
std::string lhs = l.get_string().substr(pos + 1);
pos = r.get_string().find_last_of('/');
std::string rhs = r.get_string().substr(pos + 1);
return lhs < rhs;
}
};

int main()
{
std::vector<line_t> v(
std::istream_iterator<line_t>(std::cin),
std::istream_iterator<line_t>());
std::sort(v.begin(), v.end());
std::copy(v.begin(), v.end(),
std::eek:stream_iterator<line_t>(std::cout,"\n"));

}
 
B

Bart van Ingen Schenau

Comeau is mistaking this statement for a function declaration.  I
believe Comeau is at fault, but I would love to be corrected.  You can
work around this issue with:

   std::istream_iterator<line_t> in(std::cin), end;
   std::vector<line_t> v(in, end);

No, Comeau is correct here. This is known as C++'s most vexing parse.
The declaration should be parsed as:
v is a function returning std::vector<line_t> and taking as
arguments
- a std::istream_iterator<line_t> named std::cin (with redundant
parentheses), and
- an unnamed pointer to a function returning
std::istream_iterator<line_t> and taking no arguments.

There are two ways to get the intended meaning of an object
declaration:
- Use named iterators as described by Jeff,or
- Add redundant parentheses around one or both of the constructor
arguments:
std::vector<line_t> v(
(std::istream_iterator<line_t>(std::cin)),
(std::istream_iterator<line_t>()));

Bart v Ingen Schenau
 
J

James Kanze

Comeau is mistaking this statement for a function declaration.
I believe Comeau is at fault, but I would love to be
corrected.

It's an interesting question. It looks like a function
declaration. But as Comeau says, the argument in a function
declaration cannot take a qualified name, so it can't be a
(legal) function declaration. Whether this is enough to
disqualify it as a function declaration or not, however, I don't
know. (If instead of std::cin, he had written just cin, or used
the name of a local variable, there would be no doubt that it
was a function declaration.)
You can
work around this issue with:

std::istream_iterator<line_t> in(std::cin), end;
std::vector<line_t> v(in, end);

The more or less standard solution is to put an extra pair of
parentheses around the arguments, e.g.:

std::vector<line_t> v(
(std::istream_iterator<line_t>(std::cin)),
(std::istream_iterator<line_t>()));

(Putting them around either of the arguments is sufficient, but
there's no harm in being consistent.)
 
R

red floyd

It's an interesting question.  It looks like a function
declaration.  But as Comeau says, the argument in a function
declaration cannot take a qualified name, so it can't be a
(legal) function declaration.  Whether this is enough to
disqualify it as a function declaration or not, however, I don't
know.  (If instead of std::cin, he had written just cin, or used
the name of a local variable, there would be no doubt that it
was a function declaration.)



The more or less standard solution is to put an extra pair of
parentheses around the arguments, e.g.:

  std::vector<line_t> v(
    (std::istream_iterator<line_t>(std::cin)),
    (std::istream_iterator<line_t>()));

(Putting them around either of the arguments is sufficient, but
there's no harm in being consistent.)

Thanks, guys. I didn't realize I'd hit the "most vexing parse". I'm
familiar with the issue,
but for some reason, it blew right by me. Go figure.

Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top