473,320 Members | 2,145 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

output_iterator_tag and back_insert_iterator

Hello,

I am trying to write a generic function that can read data from a file
and store it in a container.

I defined the following function:

template<class T>
void readBinaryFile(
const std::string &filename,
std::iterator<std::output_iterator_tag, Tdata)
{
....
}

Because the function is reading binary data, it needs to know the type of
the elements in the container, T.

When I call it with something like:

vector<floatf;
readBinaryFile<float>("test.bin", back_inserter(f));

I get:

error: no matching function for call to ‘readBinaryFile(std::string&,
std::back_insert_iterator<std::vector<float, std::allocator<float >)’

I am a little bit confused because I know that the back_insert_iterator
is an output iterator. In fact, back_insert_iterator is defined as:

template<typename _Container>
class back_insert_iterator
: public iterator<output_iterator_tag, void, void, void, void>

If I change the function declaration to:

template<class T, class OutputIterator>
void readBinaryFile(
const std::string &filename,
OutputIterator data)

it works fine.

If possible, I would prefer to make the first declaration work
somehow. Or at least, understand why it does not work.

Thanks,
Rares

Jun 27 '08 #1
2 1808
Rares Vernica wrote:
Hello,

I am trying to write a generic function that can read data from a file
and store it in a container.

I defined the following function:

template<class T>
void readBinaryFile(
const std::string &filename,
std::iterator<std::output_iterator_tag, Tdata)
{
...
}
You probably don't want that signature:

(a) When you pass an iterator, it will be sliced down to std::iterator,
which is a rather meaningless thing.

(b) Even if you fix that (e.g., passing the iterator by reference), you
would limit the use of your function to iterator types derived from
std::iterator< output_iterator_tag, T >. There are not that many.

You should consider:

template < typename T, typename InIter >
void readBinaryFile(
std::string const & filename,
InIter where ) {
....
}

which is much more versatile.

Because the function is reading binary data, it needs to know the type of
the elements in the container, T.

When I call it with something like:

vector<floatf;
readBinaryFile<float>("test.bin", back_inserter(f));

I get:

error: no matching function for call to ?readBinaryFile(std::string&,
std::back_insert_iterator<std::vector<float, std::allocator<float >)?

I am a little bit confused because I know that the back_insert_iterator
is an output iterator. In fact, back_insert_iterator is defined as:

template<typename _Container>
class back_insert_iterator
: public iterator<output_iterator_tag, void, void, void, void>
Note that float != void. You would want that back_inserter to be derived
from iterator< output_iterator_tag, float >, but that is _not_ what it is.
If I change the function declaration to:

template<class T, class OutputIterator>
void readBinaryFile(
const std::string &filename,
OutputIterator data)

it works fine.
Aha.
If possible, I would prefer to make the first declaration work
somehow.
No, you would not :-)
Or at least, understand why it does not work.
See above.
Best

Kai-Uwe Bux
Jun 27 '08 #2
In article <y1*************@ics.uci.edu>, ra***@ics.uci.edu says...

[ ... ]
I defined the following function:

template<class T>
void readBinaryFile(
const std::string &filename,
std::iterator<std::output_iterator_tag, Tdata)
{
...
}
That was your first mistake... :-)
Because the function is reading binary data, it needs to know the type of
the elements in the container, T.
Yup.

The function want is already implemented. It's called std::copy.

All you need to do is write an extractor that extracts an item from your
file correctly. The one problem is that there are already overloads to
read the data incorrectly (i.e. from a text file) for many built-in
types. You can overcome this by creating a proxy class, something like:

template <class T>
class binIO {
T data;
public:
operator T() const { return data; }

binIO(T value = T()) : data(value) { }

friend std::istream &operator>>(std::istream &is, binIO &f) {
return is.read((char *)&f.data, sizeof(f.data));
}
friend std::ostream &operator<<(std::ostream &os, binIO const &f) {
return os.write((char *)&f.data, sizeof(f.data));
}
};

To read (for example) a file of floats in binary format into a vector,
you'd do something like:

std::vector<floatdata;
std::ifstream in("input.dat", std::ios::binary);

std::copy(std::istream_iterator<binIO<float(in),
std::istream_iterator<binIO<float(),
std::back_inserter(data));

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jun 27 '08 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Chyi Pin Lim | last post by:
Why is the type for back_insert_iterator void and not the type of its encapsulating container? Why: namespace std { template<class Category, class T, class Distance = ptrdiff_t, class...
18
by: Joe Laughlin | last post by:
(file and class names changed to protect the innocent) g++ -Wall -c file.cpp: In member function `std::string Some_Class::get_member(const std::string&) const': file.cpp:46: passing `const...
6
by: Daniel T. | last post by:
The line marked (1) below compiles fine and does exactly what I would expect, but the line marked (2) does not compile at all on my system. error: variable or field 'bar' declared void My...
1
by: antoanish | last post by:
Hello, My Requirement is 1. Copy data from iterator to an array ( array should be created dynamically within the function based on data_type of the data held by the iterator /container. )...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.