Thread: front_inserter not working

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    56

    front_inserter not working

    I am trying to overwrite the first two elements of vec with the first two elements of cat but it is not working.
    Code:
    #include <iostream>
    #include <vector>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    int main()
    {
    	vector<string> vec;
    	vector<string> cat;
    	
    	vec.push_back("this");
    	vec.push_back("is");
    	
    	cat.push_back("a");
    	cat.push_back("test");
    	
    
    	copy( cat.begin(), cat.end(), front_inserter(vec) );
    	for( vector<string>::const_iterator it = vec.begin(); it < vec.end(); it++)
    		cout << *it << endl;
    	
    	return 0;
    }
    Here is the errors:
    Code:
    In file included from /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/bits/stl_algobase.h:69,
                     from /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/bits/char_traits.h:41,
                     from /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/ios:41,
                     from /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/ostream:40,
                     from /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/iostream:40,
                     from vec_cat.cpp:1:
    /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/bits/stl_iterator.h: In member function ‘std::front_insert_iterator<_Container>& std::front_insert_iterator<_Container>::operator=(typename _Container::const_reference) [with _Container = std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >]’:
    /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/bits/stl_algobase.h:343:   instantiated from ‘static _OI std::__copy_move<false, false, std::random_access_iterator_tag>::__copy_m(_II, _II, _OI) [with _II = std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, _OI = std::front_insert_iterator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’
    /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/bits/stl_algobase.h:397:   instantiated from ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false, _II = std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, _OI = std::front_insert_iterator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’
    /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/bits/stl_algobase.h:436:   instantiated from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false, _II = __gnu_cxx::__normal_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, _OI = std::front_insert_iterator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’
    /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/bits/stl_algobase.h:468:   instantiated from ‘_OI std::copy(_II, _II, _OI) [with _II = __gnu_cxx::__normal_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, _OI = std::front_insert_iterator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’
    vec_cat.cpp:19:   instantiated from here
    /usr/lib/gcc/i586-redhat-linux/4.4.0/../../../../include/c++/4.4.0/bits/stl_iterator.h:500: error: ‘class std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >’ has no member named ‘push_front’
    When I use back_inserter(), it copies the elements of cat to the end of vec just fine. Also, should I be #including <iterator>? I haven't done that before and I have never had a problem that I know of.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Yes, you should #include <iterator>, but then the next problem is that std::vector does not have a push_front() member function.

    EDIT:
    But if you are trying to assign the first two elements of cat to the first two elements of vec then you do not need an iterator adapter at all. However, you must be certain that vec has at least as many elements as cat, which you are certain of in this case.
    Last edited by laserlight; 06-20-2009 at 02:24 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    56
    Yes, you should #include <iterator>, but then the next problem is that std::vector does not have a push_front() member function.
    I am using front_inserter() which is part of iterator function.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So, have you looked up front_inserter, or better, front_insert_iterator?
    Quote Originally Posted by cplusplus.com
    The container must have member push_front defined (such as standard containers deque and list).

  5. #5
    Registered User
    Join Date
    Nov 2008
    Posts
    56
    I did look up front_inserter but not front_inserter_iterator.
    Parameters

    x
    Container for which the front insert iterator is constructed.
    I now understand what this means. I'm still trying to familiarize myself with the C++:Reference. Its certainly been a big help. Thanks.

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    The error clearly says vector is missing push_front, which means you can't use front_inserter with a vector. A vector is not a container of choice for inserting things in the front (consider deque).

    If you must, there's inserter:

    Code:
    copy( cat.begin(), cat.end(), inserter(vec, vec.begin()) );
    inserter / front_inserter / back_inserter are convenience functions which return a respective inserter_iterator. The reason is, functions can deduce template arguments, classes can't, therefore having a function return the class instance to be used as a temporary saves the trouble of having to specify the template arguments.


    -------
    *Edit: sorry, inserter doesn't insert each item to the front. It starts inserting at the beginning but keeps the order of inserted items. You have two choices to use inserter to the same effect:
    Code:
    copy( cat.rbegin(), cat.rend(), inserter(vec, vec.begin()) );
    reverse_copy( cat.begin(), cat.end(), inserter(vec, vec.begin()) );
    Last edited by anon; 06-20-2009 at 03:17 PM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Another option is to specialize front_inserter for vectors:

    Code:
    #include <vector>
    #include <iterator>
    #include <algorithm>
    
    namespace std {
    
    template < typename Type >
    class front_insert_iterator< vector< Type > > 
    	: public iterator< output_iterator_tag, void, void, void, void > 
    {
    	public:
    
    	typedef vector< Type >
    		container_type;
    	
    	explicit front_insert_iterator( container_type& container )
    	: container( container )
    	{	}
    
    	front_insert_iterator& operator = ( typename container_type::value_type const& value )
    	{	
    		container.resize( container.size( ) + 1 );
    		copy( container.rbegin( ) + 1, container.rend( ), container.rbegin( ) );
    		container[ 0 ] = value;		
    		return *this;
    	}
    	
    	front_insert_iterator& operator * ( void )
    	{	
    		return *this;
    	}
    	
    	front_insert_iterator& operator++ ( void )
    	{	
    		return *this;
    	}
    	
    	front_insert_iterator operator++ ( int )
    	{
    		return *this;
    	}
    	
    	protected: 
    	
    	container_type& 
    		container;
    };
    
    } // namespace std
    
    #include <iostream>
    #include <iterator>
    
    using namespace std;
    
    int main( void )
    {
    	string
    		text = "in girum imus nocte et consumimur igni";
    	vector< char >
    		reversed;
    	copy( text.begin( ), text.end( ), front_inserter( reversed ) );
    	copy( reversed.begin( ), reversed.end( ), ostream_iterator< char, char >( cout ) );
    	cout << endl;
    	return 0;
    }
    I think that's correct, anyway.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Sebastiani
    Another option is to specialize front_inserter for vectors:
    A better option would probably be to switch to a container that supports push_front(), since for such a container push_front() would be a constant time operation, unlike the case for std::vector.

    Incidentally, this:
    Code:
    container.resize( container.size( ) + 1 );
    copy( container.rbegin( ) + 1, container.rend( ), container.rbegin( ) );
    container[ 0 ] = value;
    could be simplified to:
    Code:
    container.insert(container.begin(), value);
    However, as I noted in my edit to post #2, I think that iterator adapters are not appropriate here: swappo stated that he/she wants "to overwrite the first two elements of vec with the first two elements of cat", thus no insertions are necessary.
    Last edited by laserlight; 06-21-2009 at 12:24 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> A better option would probably be to switch to a container that supports push_front(), since for such a container push_front() would be a constant time operation, unlike the case for std::vector.

    Probably, but it is useful to be able to do it with a vector, if you're stuck with one.

    >> could be simplified to:

    Right, I completely overlooked that.

    >> However, as I noted in my edit to post #2, I think that iterator adapters are not appropriate here: swappo stated that he/she wants "to overwrite the first two elements of vec with the first two elements of cat", thus no insertions are necessary.

    Whoops.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Function not working
    By sloopy in forum C Programming
    Replies: 31
    Last Post: 11-12-2005, 08:08 PM
  2. Program Not working Right
    By raven420smoke in forum C++ Programming
    Replies: 2
    Last Post: 09-16-2005, 03:21 AM
  3. Trying to eject D drive using code, but not working... :(
    By snowfrog in forum C++ Programming
    Replies: 3
    Last Post: 05-07-2005, 07:47 PM
  4. x on upper right corner not working
    By caduardo21 in forum Windows Programming
    Replies: 1
    Last Post: 02-20-2005, 08:35 PM
  5. cygwin -> unix , my code not working properly ;(
    By CyC|OpS in forum C Programming
    Replies: 4
    Last Post: 05-18-2002, 04:08 AM