C ++ 11 automatic iterator type using std :: begin (), std :: end () issue

I have a private class member representing a std::deque random access array containing some data:

 std::vector<std::deque<SomeDataClass> > someMember; 

I would like to provide a public class method that returns an iterable data structure containing all the data elements from my deques array:

 std::deque<SomeDataClass> someMethod(); 

I would like this method to go through all the characters in the vector and copy every element on it to the local std :: deque, resulting in returning this local std :: deque by value. I am trying to implement this method using C ++ 11 auto and std::begin() , std::end() :

 std::deque<SomeDataClass> MyClassName::someMethod(){ std::deque<DirectedEdge> allDataItems; std::deque<DirectedEdge>::iterator deqIter = allDataItems.begin(); for(auto it = std::begin(someMember); it != std::end(someMember); ++it){ std::copy(std::begin(*it), std::end(*it), deqIter); } return allDataItems; } 

I get an error accessing an unhandled data exception at runtime in the deque header. What is a mistake?

+7
c ++ c ++ 11 std
source share
2 answers

std::copy() requires the destination range to be large enough to hold the copy, but allDataItems empty. You need to reserve a place in allDataItems in advance (but this is not possible with std::deque ). Instead, use std::back_inserter (defined in <iterator> ):

 std::deque<SomeDataClass> MyClassName::someMethod(){ std::deque<DirectedEdge> allDataItems; for(auto it = std::begin(someMember); it < std::end(someMember); ++it){ std::copy(std::begin(*it), std::end(*it), std::back_inserter(allDataItems)); } return allDataItems; } 
+13
source share

Here is the ideological way of C + 11:

 std::deque<SomeDataClass> MyClassName::someMethod() { std::deque<DirectedEdge> allDataItems; for( auto const& dq : someMember ) { allDataItems.insert( allDataItems.end(), std::begin(dq), std::end(dq) ); } return allDataItems; } 

another way would be to write a concatinate function:

 struct concatenate { template<typename Dest, typename Src> Dest&& operator()( Dest&& d, Src const& s ) const { using std::begin; using std::end; typename std::decay<Dest>::type retval = std::forward<Dest>(d); retval.insert( end(retval), begin(s), end(s) ); return std::move(retval); } }; std::deque<SomeDataClass> MyClassName::someMethod() { using std::begin; using std::end; // enable ADL return std::accumulate( begin(someMember), end(someMember), std::deque<DirectedEdge>(), concatenate() ); } 

which is pretty pretty. If you do not like std::accumulate ,

 std::deque<SomeDataClass> MyClassName::someMethod() { std::deque<DirectedEdge> allDataItems; for( auto const& dq : someMember ) { allDataItems = concatenate( std::move(allDataItems), dq ); } return allDataItems; } 

both of them are roughly equivalently effective.

+4
source share

All Articles