tags:

views:

446

answers:

4

I'm trying to initialize a vector using iterators and I'm getting a compiler error basically saying that there's no matching function to call.

The code reads from a file with an istream_iterator and ends with an input sentinel. Then I try to initialize the vector with those two iterators.

#include "std_lib_facilities.h"
#include<iterator>

int main()
{
    string from, to;    // get source and target file names
    cin >> from >> to;

    ifstream is(from.c_str()); // open input stream
    ofstream os(to.c_str());   // open output stream

    istream_iterator<string> ii(is);    // make input iterator for stream
    istream_iterator<string> eos;   // input sentinel
    ostream_iterator<string> oo(os,"\n");

    vector<string> words(ii, eos);  // vector initialized from input
    sort(words.begin(), words.end());   // sort the buffer
    copy(words.begin(), words.end(), oo);  // copy buffer to output
}

I know I could use the copy function to copy the input stream into the vector, but I read that it can be done this way as well. Can anyone explain why this is not compiling? Thanks.

Compiler error:

C:\Users\Alex\C++\stream_iterators.cpp|16|error: no matching function for call to `Vector<String>::Vector(std::istream_iterator<String, char, std::char_traits<char>, ptrdiff_t>&, std::istream_iterator<String, char, std::char_traits<char>, ptrdiff_t>&)'|

Edit: It is not a header problem. Std_lib_facilities has all of the needed headers.

A: 
vector<string> words(ii, eos);

is an analogue to

vector<string> words;
copy( ii, eos, back_inserter(words) );

vector class has the following constructor:

// initialize with range [First, Last)
template<class InputIterator>
   vector(
      InputIterator First,
      InputIterator Last
   );

To make your sample compiling you need to include the following:

#include <sstream>
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm> // for std::copy

Since your identifiers not fully qualified you should add the following:

using namespace std;

Or fully qualify all STL identifiers.

And to change, I guess,

copy(words.begin(), words.end(), out)

to

copy(words.begin(), words.end(), oo)
Kirill V. Lyadvinsky
Yes, but it's not compiling.
trikker
Which part? Did you include all required headers?
Kirill V. Lyadvinsky
std_lib_facilities include all of the required headers except <iterator>, and I've included <iterator> for that.
trikker
std_lib_facilities includes all of these headers
trikker
Do you have `using namespace std;` in `#include "std_lib_facilities.h"` ?
Kirill V. Lyadvinsky
Yes. The documentation can be found here. http://www.stroustrup.com/Programming/std_lib_facilities.h
trikker
It compiles without errors for me. What compiler do you use?
Kirill V. Lyadvinsky
A: 

Please copy and paste the compiler error. Also you are missing a number of headers such as algorithm and vector. You need a use namespace std declaration or use std:: to access the STL classes.

Once you provide more information we can give you more advice.

Update: why is your error message referring to "Vector" (with capital), not vector (lower case)?

teambob
These headers are included in the std_lib_facilities header.
trikker
A: 

The book header had some kind of compliance issues, so I just included the appropriate headers and it worked.

trikker
A: 

The Vector class in std_lib_facilities.h defines three constructors, but not one which accepts a pair of iterators. You can go ahead and add that to the header:

template <class Iter>
Vector(Iter from, Iter to): std::vector<T>(from, to) {}

With this header you'll need to take into account that this is for hand-holding. operator[] in a real std::vector is not supposed to do range-checking. (Why not just teach beginners to use vector::at instead, until they get the idea that it might be better to stay in bounds...?)

UncleBens