views:

153

answers:

3

When trying to compile the following:

#include <string>
#include <iterator>
#include <iostream>
using namespace std;
int main() {
  string s(istream_iterator<char>(cin), istream_iterator<char>());
  return s.size();
}

g++ 4.4.1 gives me:

main.cc: In function ‘int main()’:
main.cc:6: error: request for member ‘size’ in ‘s’, which is of non-class type ‘std::string(std::istream_iterator<char, char, std::char_traits<char>, int>, std::istream_iterator<char, char, std::char_traits<char>, int> (*)())’

According to libstdc++ docs, string has a ctor that takes a begin/end iterator pair. Why do I get this error, then?

+5  A: 

You're accidentally declaring a function instead of instantiating a string. Try declaring variables for your istream_iterator objects and then passing those to the std::string constructor.

And here's a good read that describes exactly your problem: http://www.gotw.ca/gotw/075.htm

Fred Larson
Or: string s = string(istream_iterator<char>(cin), istream_iterator<char>());
Nate Kohl
I prefer Nate Kohl's approach too, it's not much costly (in term of typing) and the copy is probably optimized away anyway.
Matthieu M.
@Mattieu M., if you look at Herb Sutter's declaration, I think it's actually less typing since you don't have to repeat the "istream_iterator<char>" boilerplate. These variables are probably also optimized away, and Herb prefers it "because it's much easier to get right, it's utterly understandable to even the weakest compilers, and it makes the code clearer to read to boot."
Fred Larson
+3  A: 

Search for "most vexing parse", and you'll find more than you want to know.

The bottom line is that the compiler is interpreting your two parameters as specifying types instead of values. That, in turn, leads it to interpret your definition as being a declaration of a function instead.

Jerry Coffin
+3  A: 

You've declared a function instead of variable. Write the following to fix:

string s(istream_iterator<char>(cin), (istream_iterator<char>()));
Kirill V. Lyadvinsky