By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,417 Members | 1,057 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,417 IT Pros & Developers. It's quick & easy.

Vector reserve in a for_each

P: n/a
I have a vector of vectors:
vector< vector<double v;
and have initialized it with:
v( 5 );
as I know I will have 5 columns of data. At this point, I read text file
data into each of the the vectors using push_back. I know that I will be
reading in 5000 elements into each vector, so I use reserve:
ifstream f( "file.txt" );
if(f.is_open())
{
for( vector< vector<double::iterator itr = v.begin();
itr != v.end(); ++itr )
{
itr->reserve(5000);
}
double d;
while(f >d)
{
m_data[0].push_back( d );
f >d;
m_data[1].push_back( d );
f >d;
m_data[2].push_back( d );
f >d;
m_data[3].push_back( d );
f >d;
m_data[4].push_back( d );
}
}
However, could I use a for_each to set the reserve of the vectors? Or is
there a different/better way to read in the 5 column text data?

Thanks in advance.
Feb 24 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a
* Chris Roth:
I have a vector of vectors:
vector< vector<double v;
and have initialized it with:
v( 5 );
as I know I will have 5 columns of data. At this point, I read text file
data into each of the the vectors using push_back. I know that I will be
reading in 5000 elements into each vector, so I use reserve:
ifstream f( "file.txt" );
if(f.is_open())
{
for( vector< vector<double::iterator itr = v.begin();
itr != v.end(); ++itr )
{
itr->reserve(5000);
}
double d;
while(f >d)
{
m_data[0].push_back( d );
f >d;
m_data[1].push_back( d );
f >d;
m_data[2].push_back( d );
f >d;
m_data[3].push_back( d );
f >d;
m_data[4].push_back( d );
}
}
However, could I use a for_each to set the reserve of the vectors?
You could, but a loop is much cleaner.

However, I'd use an indexing loop, not an iterator-based loop.

Like

for( size_t i = 0; i < v.size(); ++i ) { v.at(i).reserve( 5000 ); }

Or is
there a different/better way to read in the 5 column text data?
Sure: define "better".

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 24 '07 #2

P: n/a
>
You could, but a loop is much cleaner.

However, I'd use an indexing loop, not an iterator-based loop.

Like

for( size_t i = 0; i < v.size(); ++i ) { v.at(i).reserve( 5000 ); }
A voice of sanity, some people go completely overboard on writing
generic loops. Although I'd use [] not at for this very simple case.

john
Feb 24 '07 #3

P: n/a
A voice of sanity, some people go completely overboard on writing
generic loops.
http://www.regdeveloper.co.uk/2006/0...lusplus_loops/
Feb 24 '07 #4

P: n/a
Chris Roth wrote:
I have a vector of vectors:
vector< vector<double v;
and have initialized it with:
v( 5 );
as I know I will have 5 columns of data. At this point, I read text file
data into each of the the vectors using push_back. I know that I will be
reading in 5000 elements into each vector, so I use reserve:
ifstream f( "file.txt" );
if(f.is_open())
{
for( vector< vector<double::iterator itr = v.begin();
itr != v.end(); ++itr )
{
itr->reserve(5000);
}
double d;
while(f >d)
{
m_data[0].push_back( d );
f >d;
m_data[1].push_back( d );
f >d;
m_data[2].push_back( d );
f >d;
m_data[3].push_back( d );
f >d;
m_data[4].push_back( d );
}
}
However, could I use a for_each to set the reserve of the vectors? Or is
there a different/better way to read in the 5 column text data?

Thanks in advance.
Here's how you'd do it. But I would comment that in the amount of time
it took me to get the syntax just right I could have written the
equivalent for loop a hundred times over.

#include <vector>
#include <functional>
#include <algorithm>

int main()
{
std::vector< std::vector<double v(5) ;

std::for_each(v.begin(), v.end(),
std::bind2nd(std::mem_fun_ref(&std::vector<double> ::reserve),
5000)) ;
}

--
Alan Johnson
Feb 24 '07 #5

P: n/a
John Harrison wrote:
>
>A voice of sanity, some people go completely overboard on writing
generic loops.

http://www.regdeveloper.co.uk/2006/0...lusplus_loops/
Best quote from that article:

"Don't be silly, it's an int! The day they change the language name to
++C, that's the day I'll start taking pre-incrementing seriously."

From now on I will be referring to C++ and ++C. :)

--
Alan Johnson
Feb 24 '07 #6

P: n/a
On 24 Feb, 08:42, Alan Johnson <a...@yahoo.comwrote:
Chris Roth wrote:
I have a vector of vectors:
vector< vector<double v;
and have initialized it with:
v( 5 );
as I know I will have 5 columns of data. At this point, I read text file
data into each of the the vectors using push_back. I know that I will be
reading in 5000 elements into each vector, so I use reserve:
ifstream f( "file.txt" );
if(f.is_open())
{
for( vector< vector<double::iterator itr = v.begin();
itr != v.end(); ++itr )
{
itr->reserve(5000);
}
double d;
while(f >d)
{
m_data[0].push_back( d );
f >d;
m_data[1].push_back( d );
f >d;
m_data[2].push_back( d );
f >d;
m_data[3].push_back( d );
f >d;
m_data[4].push_back( d );
}
}
However, could I use a for_each to set the reserve of the vectors? Or is
there a different/better way to read in the 5 column text data?
Thanks in advance.

Here's how you'd do it. But I would comment that in the amount of time
it took me to get the syntax just right I could have written the
equivalent for loop a hundred times over.
Somehow I just feel that things could be so much sweeter...

#include <algorithm>
#include <functional>
#include <vector>
#include <iostream>
#include <boost/preprocessor/cat.hpp>

#define CONTAINER_FUN_ADAPT1(ret,fun,arg) \
namespace impl{\
struct BOOST_PP_CAT(fun,_fun){\
arg v;\
BOOST_PP_CAT(fun,_fun)(arg v_in)\
: v(v_in){}\
template <typename C>\
ret operator()( C & c)const\
{\
c. fun(v);\
}\
};\
}\
impl::BOOST_PP_CAT(fun,_fun) fun( arg v)\
{\
return impl::BOOST_PP_CAT(fun,_fun)(v);\
}\

namespace my{

// reserve space in a container adaptor
CONTAINER_FUN_ADAPT1(void,reserve,size_t);

// wrap ugly std:: syntax
template <typename Seq, typename F>
void for_each(Seq & seq,F const & f)
{
std::for_each(seq.begin(),seq.end(),f);
}
}

int main()
{
//--------ugly --------------

std::vector< std::vector<double v1(5) ;

std::for_each(
v1.begin(), v1.end(),
std::bind2nd(
std::mem_fun_ref(
&std::vector<double>::reserve
),
5000
)
);
//check it worked...
std::cout << (int) v1[2].capacity() <<'\n';

//----- pretty ---------------

std::vector< std::vector<double v2(5) ;

my::for_each(v2,my::reserve(5000));

//check it worked...
std::cout << (int) v2[2].capacity() <<'\n';

}


Feb 24 '07 #7

P: n/a
kwikius wrote:
On 24 Feb, 08:42, Alan Johnson <a...@yahoo.comwrote:
>Chris Roth wrote:
>>I have a vector of vectors:
vector< vector<double v;
and have initialized it with:
v( 5 );
as I know I will have 5 columns of data. At this point, I read text file
data into each of the the vectors using push_back. I know that I will be
reading in 5000 elements into each vector, so I use reserve:
ifstream f( "file.txt" );
if(f.is_open())
{
for( vector< vector<double::iterator itr = v.begin();
itr != v.end(); ++itr )
{
itr->reserve(5000);
}
double d;
while(f >d)
{
m_data[0].push_back( d );
f >d;
m_data[1].push_back( d );
f >d;
m_data[2].push_back( d );
f >d;
m_data[3].push_back( d );
f >d;
m_data[4].push_back( d );
}
}
However, could I use a for_each to set the reserve of the vectors? Or is
there a different/better way to read in the 5 column text data?
Thanks in advance.
Here's how you'd do it. But I would comment that in the amount of time
it took me to get the syntax just right I could have written the
equivalent for loop a hundred times over.

Somehow I just feel that things could be so much sweeter...

#include <algorithm>
#include <functional>
#include <vector>
#include <iostream>
#include <boost/preprocessor/cat.hpp>

#define CONTAINER_FUN_ADAPT1(ret,fun,arg) \
namespace impl{\
struct BOOST_PP_CAT(fun,_fun){\
arg v;\
BOOST_PP_CAT(fun,_fun)(arg v_in)\
: v(v_in){}\
template <typename C>\
ret operator()( C & c)const\
{\
c. fun(v);\
}\
};\
}\
impl::BOOST_PP_CAT(fun,_fun) fun( arg v)\
{\
return impl::BOOST_PP_CAT(fun,_fun)(v);\
}\

namespace my{

// reserve space in a container adaptor
CONTAINER_FUN_ADAPT1(void,reserve,size_t);

// wrap ugly std:: syntax
template <typename Seq, typename F>
void for_each(Seq & seq,F const & f)
{
std::for_each(seq.begin(),seq.end(),f);
}
}

int main()
{
//--------ugly --------------

std::vector< std::vector<double v1(5) ;

std::for_each(
v1.begin(), v1.end(),
std::bind2nd(
std::mem_fun_ref(
&std::vector<double>::reserve
),
5000
)
);
//check it worked...
std::cout << (int) v1[2].capacity() <<'\n';

//----- pretty ---------------

std::vector< std::vector<double v2(5) ;

my::for_each(v2,my::reserve(5000));

//check it worked...
std::cout << (int) v2[2].capacity() <<'\n';

}

This thread is a good example of why C++ needs lambda functions (or
anonymous functions, or function literals, or whatever you want to call
them). The concept of doing the same thing to every item in a container
is arguably the most common algorithm one would apply to a container,
but use C++'s for_each is just such a pain.

Either you need to write a functor, which typically needs to be a full
blown class with at least operator() and a constructor that wraps up
enough of the local state to be useful, or you have to play around with
binders and generic function objects. boost::function and boost::bind
seem like the answer for the few moments until you actually try to do
something non-trivial with them, like compose two functions that are
created by binding parameters on two other functions, at which point you
realize that because this is all just a library hack, you have to
surround the inner binds with a boost::protect. And lord help you if
you are trying to do any of this in a scope where it isn't convenient to
add a "using namespace boost ;".

Typically after struggling with indecipherable compiler errors for an
hour or so, most people just give up and spend 2 minutes writing a for loop.

--
Alan Johnson
Feb 25 '07 #8

P: n/a
On 25 Feb, 00:58, Alan Johnson <a...@yahoo.comwrote:
kwikius wrote:
<...>
This thread is a good example of why C++ needs lambda functions (or
anonymous functions, or function literals, or whatever you want to call
them). The concept of doing the same thing to every item in a container
is arguably the most common algorithm one would apply to a container,
but use C++'s for_each is just such a pain.
One problem with a lot of standard library algorithms is the emphasis
on iterators. Its annoying with for_each but starts to become
ridiculous in functions action on two containers of which there are a
lot. In many cases it seems to me that it would be trivial to hide
iterators in the implementation, and use a e.g boost::range where only
some part needs to be accessed( which IMO isnt as common as moving
through the whole sequence). A function with 3 arguments is much more
manageable to use and read and comprehend than one with 5. Note also
that typos in argument such as providing an InputIterator2 instead of
InputIterator1 would be eliminated, which currently won't necessarily
be caught even at runtime currently.
Either you need to write a functor, which typically needs to be a full
blown class with at least operator() and a constructor that wraps up
enough of the local state to be useful, or you have to play around with
binders and generic function objects. boost::function and boost::bind
seem like the answer for the few moments until you actually try to do
something non-trivial with them, like compose two functions that are
created by binding parameters on two other functions, at which point you
realize that because this is all just a library hack, you have to
surround the inner binds with a boost::protect. And lord help you if
you are trying to do any of this in a scope where it isn't convenient to
add a "using namespace boost ;".

Typically after struggling with indecipherable compiler errors for an
hour or so, most people just give up and spend 2 minutes writing a for loop.
Yes, but... Personally I find the case for anonymous stateful
functions in C++ not entirely convincing from what I have seen so far.

Firstly by nature an anonymous function is not reusable. That means
each expression using it needs testing and in all probability exactly
the same expression will be reimplemented over and over. The use of
named functions at namespace scope is by nature reusable and can be
transferred into a header in a nice modular fashion. So for example
the reserve function in my last post has now been added to my code
base. It will probably never be used but nevertheless it sits in a
header on my hard disc doing no harm. If it does get used for anything
serious then it will need some tests but again once done the thing is
modular and doesnt need to be repeated.

The second problem is that anonymous functoids or whatever they are
called make code look a mess. Everything is inline in the expresion.
The only examples I have seen in C++ are pretty trivial but you can
see the true nature of the junk produced when used seriously, by
looking at some source code in a FP language such as OCaml. The nested
inlining of functions within expressions makes code horrible to read
and probably horrible to maintain.

Also from what I have sen it looks like implementing them and sorting
the design is extremely complicated. Is any benefit worth it?

AFAICS the C++ powers that be seem to be concentrating on ever more
complicated language features of which 'lambda' is one. The proponents
of rival languages to C++ must be smirking into their sleeves at
this. C++ is already probably the most difficult language to master,
and once mastered it has a paltry out of date standard library. Even
OCaml has a graphics library !. It seems obvious to me that the
attraction of Java and C# is the "standard" libraries bundled rather
than the language itself hence their success in recent years.

Anyway FWIW here is some more code with the same simple trick of using
overloaded functions to avoid the need for providing long winded
template args to functors. I figured I should output the capacity of
the vectors in the sequence to check the code. Again The (named)
functions provide the interface and the functors the implementation.
The quan::fun:: headers arent shown but its pretty trivial to
replicate their functionality.

And of course its all doable in the current language. Thank goodnees
for the preprocessor ;-)
regards
Andy Little

// headers from a useful little
// (now quite extensive in fact)

// library of homebrewed
// functional bits and pieces.
// (The quan::fun library is based on the boost::fusion
// library but without the emphasis on iterators or MPL).

#include <quan/fun/output.hpp>
#include <quan/fun/for_each.hpp>

// work from previous example added to the jumble...
#include <quan/fun/container_reserve.hpp>
// probably will never be used but
// its doing no harm sitting on the hard disk
// the CONTAINER_FUN_ADAPT1 macro is also reusable
// so creating adaptors for other members functions
// is trivial and the container_reserve header
// provides docs on the syntax when I forget it :-)
#include <vector>
#include <iostream>
#include <boost/preprocessor/cat.hpp>

// need a new adapter for vector.capacity
// this can be reused same as the above
// container_reserve header
// Reuse! just copy pasted from the old macro
// and chopped about a bit

#define CONTAINER_FUN_ADAPT0(ret,fun) \
namespace impl_detail{\
struct BOOST_PP_CAT(fun,_fun){\
template <typename C>\
ret operator()( C & c)const\
{\
return c. fun();\
}\
};\
}\
impl_detail::BOOST_PP_CAT(fun,_fun) fun()\
{\
return impl_detail::BOOST_PP_CAT(fun,_fun)();\
}

namespace quan{ namespace fun{
// get capacity of a container
// using long long return supresses size_t
// conversion warnings for output.
// because the functor doesnt know about the container
// except in it function op
// its not possible to use the member::size_type
#ifdef BOOST_HAS_LONG_LONG
CONTAINER_FUN_ADAPT0(long long,capacity);
#else
CONTAINER_FUN_ADAPT0(size_t,capacity);
#endif

} }
namespace quan{ namespace fun{namespace impl_detail{

// implementation functor to output a function of its argument
// to an ostream. (implemented here to output vect.capacity())
// interface : quan::fun::output(stream, Fun, sep)
// complements straight quan::fun::output(out, sep) function
// which just outputs the value...

template <typename Fun,typename CharType>
struct output_fun{
Fun const & fun;
std::basic_ostream<CharType& os;
std::basic_string<CharTypesep;
output_fun(
std::basic_ostream<CharType& os_in,
Fun const & fun_in,
std::basic_string<CharTypeconst & sep_in
):os(os_in), fun(fun_in), sep(sep_in){}

template <typename T>
struct result{
typedef std::basic_ostream<CharType& type;
};

template <typename T>
typename result<T>::type
operator()(T const & t)const
{
return os << fun(t) << sep;
}
};
}//impl_detail

// interface functions
// original quan::fun::output(stream, sep) function
// is trivially overloaded to
// return the different functor above
template <typename Fun,typename CharType>
inline
impl_detail::output_fun<Fun,CharType>
output(
std::basic_ostream<CharType>& os,
Fun const & fun,
std::basic_string<CharType>const & sep
)
{
return impl_detail::output_fun<Fun,CharType>(os,fun,sep);
}
// needs const char* overload as std::string<CharType>
// cannot be deduced from CharType* in this context
template <typename Fun,typename CharType>
inline
impl_detail::output_fun<Fun,CharType>
output(
std::basic_ostream<CharType>& os,
Fun const & fun,
const CharType* sep
)
{
return output(os,fun,std::basic_string<CharType>(sep));
}

}}

int main()
{

using quan::fun::for_each;
using quan::fun::for_each_and_last;
using quan::fun::capacity;
using quan::fun::reserve;
using quan::fun::output;

std::vector< std::vector<double v2(5) ;

for_each(v2,reserve(5000));

// check it worked..

// for_each_and_last...
// like for each but uses second function on last element
// used here to get a separator except for last element
// which gives return character

for_each_and_last(
v2,
output(std::cout,capacity() , " "),
output(std::cout,capacity() , "\n")
);
}
/*
??>test
5000 5000 5000 5000 5000

??>
*/

Feb 25 '07 #9

P: n/a
Alan Johnson wrote:
John Harrison wrote:
>>
>>A voice of sanity, some people go completely overboard on writing
generic loops.

http://www.regdeveloper.co.uk/2006/0...lusplus_loops/

Best quote from that article:

"Don't be silly, it's an int! The day they change the language name to
++C, that's the day I'll start taking pre-incrementing seriously."

From now on I will be referring to C++ and ++C. :)
My favorite is:

"If the C++ overlords believe that the construction of nearly every loop
should be a sort of inline Sudoku puzzle, surely the problem must be that
we are simply too stupid to use the language?"

Mar 2 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.