Re: Why no std::back_insert_iterator::value_type?
Ganesh wrote:
Previously, I just returned a vector<MyType>, forcing a container, a
copy,
and a type.
Previously? I'm sorry but I can't follow you there. You did not post any
"previous" code to refer to. How could you expect people to understand?
I wanted to be more flexible, allowing the user to specify any
convertible
type, avoid an unnecessary copy,
and let her pick whatever container.
Please provide us a *working* code snippet of what you have but you
don't like and some (obviously not working, but hopefully clarifying)
code of what you would like to have. Otherwise we (both you and I) are
just losing our time.
Sorry, I've been guilty of that on several posts recently. I'm in a hurry.
Here's some runnable code that illustrates my point.
It contains my previous code, that used a vector<MyType>, where MyType is
uint8_t.
I wanted to allow the user to use the container of her choice and a
reasonable type too.
Thats the "current" version.
Then, I show the code that I wish would work, but it doesn't because
value_type for back_inserter is void.
Thanks for your help.
terry
======================================
#undef KLUDGE // Define this to make this program compile.
#include <vector>
#include <list>
#include <cstddef>
#include <iterator>
#include <algorithm>
#include <iostream>
using namespace std;
typedef unsigned char uint8_t;
typedef vector<uint8_t> MyType;
typedef vector<unsigned> UserType;
// Here's what I had before.
vector<MyType> CopyOut(const uint8_t* src, size_t size,
unsigned count)
{
vector<MyType> rval;
rval.reserve(count);
// Align values on 32-bit boundaries.
size_t stride = 4*((size+3)/4);
while (count--) {
rval.push_back(MyType(src, src+size));
src += stride;
}
return rval;
} // CopyOut
// Here's what I have now.
template <class T, class OutIter>
OutIter CopyOut(OutIter dst, const uint8_t* src, size_t size,
unsigned count)
{
// Align values on 32-bit boundaries.
size_t stride = 4*((size+3)/4);
while (count--) {
*dst++ = T(src, src+size);
src += stride;
}
return dst;
} // CopyOut
// Here's what I wish would work. Doesn't need T parameter.
template <class OutIter>
OutIter CopyOutWish(OutIter dst, const uint8_t* src, size_t size,
unsigned count)
{
#ifndef KLUDGE
// Oops! iterator_traits<OutIter>::value_type is 'void'.
typedef typename iterator_traits<OutIter>::value_type DstType;
#else
typedef UserType DstType;
#endif
// Align values on 32-bit boundaries.
size_t stride = 4*((size+3)/4);
while (count--) {
*dst++ = DstType(src, src+size);
src += stride;
}
return dst;
} // CopyOutWish
struct PseudoMemory {
uint8_t data[64];
PseudoMemory() {
for (int i=0; i!=sizeof(data); ++i)
data[i] = uint8_t(i);
} // ctor
}; // PseudoMemory;
PseudoMemory Memory;
void PrintMine(const MyType& x) {
copy(x.begin(), x.end(), ostream_iterator<unsigned>(cout, " "));
cout << endl;
} // PrintMine
void PrintUser(const UserType& x) {
copy(x.begin(), x.end(), ostream_iterator<unsigned>(cout, " "));
cout << endl;
} // PrintUser
int main() {
cout << endl << "Demonstrate previous method." << endl;
vector<MyType> myResult = CopyOut(&Memory.data[4], 3, 5);
for_each(myResult.begin(), myResult.end(), PrintMine);
cout << endl << "Demonstrate current method." << endl;
list<UserType> userResult;
(void) CopyOut<UserType>(back_inserter(userResult),
&Memory.data[4], 3, 5);
for_each(userResult.begin(), userResult.end(), PrintUser);
cout << endl << "Demonstrate wishful method." << endl;
userResult.clear();
(void) CopyOutWish(back_inserter(userResult),
&Memory.data[4], 3, 5);
for_each(userResult.begin(), userResult.end(), PrintUser);
return EXIT_SUCCESS;
} // main
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]