Thread: back_inserter() and string

  1. #1
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663

    back_inserter() and string

    This won't work in VC++6:
    Code:
    #include <iostream>
    #include <string>
    #include <algorithm>
    
    using namespace std;
    
    int main()
    {
    	const int size = 3;
    	char myArray[size] = {'y', 'e', 's'};
    	
    	string str;
    	copy(myArray, myArray + size, back_inserter(str));
    	cout<<str<<endl;
    
    	return 0;
    };
    I get the error:
    error C2039: 'push_back' : is not a member of 'basic_string<char,struct std::char_traits<char>,class std::allocator<char> >'
    c:\program files\c++microsoft visual studio\vc98\include\iterator(82) : while compiling class-template member function 'class std::back_insert_iterator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >
    &__thiscall std::back_insert_iterator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::operator =(const char &)'
    Error executing cl.exe.
    back_inserter() calls push_back() for the container, and the string class has a push_back() member function, so is that a compiler bug, or am I doing something wrong?
    Last edited by 7stud; 03-05-2006 at 10:05 PM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Looks like a MSVC6 bug, or rather a pre-standard implementation of basic_string that lacks push_back(). A quick search seems to confirm that.

    It works on MSVC8 and MinGW port of GCC 3.4.2
    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
    Apr 2003
    Posts
    2,663
    A quick search seems to confirm that.
    I went to dinkumware and looked at their list of library fixes for VC5 and VC6, but they don't have anything listed for that.

    Looks like a MSVC6 bug, or rather a pre-standard implementation of basic_string that lacks push_back()
    When I click on the error in VC6, it takes me here:
    Code:
    // TEMPLATE CLASS back_insert_iterator
    template<class _C>
    	class back_insert_iterator
    		: public iterator<output_iterator_tag, void, void> {
    public:
    	typedef _C container_type;
    	typedef _C::value_type value_type;
    	explicit back_insert_iterator(_C& _X)
    		: container(_X) {}
    	back_insert_iterator<_C>& operator=(
    		const value_type& _V)
    		{container.push_back(_V);
    		return (*this); }
    	back_insert_iterator<_C>& operator*()
    		{return (*this); }
    	back_insert_iterator<_C>& operator++()
    		{return (*this); }
    	back_insert_iterator<_C> operator++(int)
    		{return (*this); }
    So, it looks like push_back() is in there, but for some reason it doesn't work.

    Thanks.
    Last edited by 7stud; 03-05-2006 at 10:36 PM.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I went to dinkumware and looked at their list of fixes for VC5 and VC6, but that don't have anything listed for that.
    I did that too after replying :P
    Does seem very strange. Have you tried using string::push_back() directly, to confirm that it isnt a problem with back_inserter()'s implementation?

    EDIT:
    okay, so it gets stranger and stranger.

    So, it looks like push_back() is in there, but for some reason it doesn't work.
    hmm... isnt that just the use of push_back()? If the class type doesnt have a push_back(), then it should complain about it, just like what its doing.
    Last edited by laserlight; 03-05-2006 at 10:41 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

  5. #5
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Quote Originally Posted by laserlight
    I did that too after replying :P
    Does seem very strange. Have you tried using string::push_back() directly, to confirm that it isnt a problem with back_inserter()'s implementation?
    Nope. I wasn't smart enough to think of that. This doesn't work either:
    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
    	string str = "hello";
    	cout<<str<<endl;
    
    	str.push_back('a');
    	cout<<str<<endl;
    
    	return 0;
    };
    error C2039: 'push_back' : is not a member of 'basic_string<char,struct std::char_traits<char>,class std::allocator<char> >'
    Error executing cl.exe.

  6. #6
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    On second thought, that error in red I posted doesn't mean push_back() is present in the string class: the code is trying to call push_back() for the container, and apparently the compiler can't find it.
    Last edited by 7stud; 03-05-2006 at 10:51 PM.

  7. #7
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    I found this small snippet on google:
    VC6 has a pre-standard library in which std::string::push_back is not
    present, which might be the source of the confusion.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Maybe that can be fixed. If MSVC6's implementation of of basic_string has insert() and end(), one might be able to implement push_back() with the equivalent of an insert(end(), char_value)
    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
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Yep. There are many different ways to accomplish the same thing, e.g. append(), insert(). I was exploring some of the alternatives when I discovered that back_inserter() wouldn't work.

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    += is another option - the only one actually that can simply take a single character.
    The problem is that std::string is precompiled in MSVC - you cannot simply change the source and expect it to work.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    += is another option
    I don't really see how. The idea was to insert a range of values into a string.

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Could be that CornedBee meant that operator+= could be used to implement push_back().
    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

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I was talking about its parallel to push_back(), as laserlight described, not its relation to the original question.

    Of course, insert() or append() or even assign() are a better choice even than std::copy for the original problem.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed