Logo Questions Linux Laravel Mysql Ubuntu Git Menu

STL operator= behavior change with Visual Studio 2010?

I am attempting to compile QtScriptGenerator (gitorious) with Visual Studio 2010 (C++) and have run into a compile error. In searching for a solution, I have seen occasional references to compile breakages introduced since VS2008 due to changes in VS2010's implementation of STL and/or c++0x conformance changes.

Any ideas what is happening below, or how I could go about fixing it? If the offending code appeared to be QtScriptGenerator's, I think I would have an easier time fixing it.. but it appears to me that the offending code may be in VS2010's STL implementation and I may be required to create a workaround?

PS. I am pretty unfamiliar with templates and STL. I have a background in embedded and console projects where such things have until recently often been avoided to reduce memory consumption and cross-compiler risks.

Edit - It appears it is probably Visual Studio's implementation of std::copy which changed.

    C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xutility(275) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'rpp::pp_output_iterator<_Container>' (or there is no acceptable conversion)
            c:\qt\qtscriptgenerator\generator\parser\rpp\pp-iterator.h(75): could be 'rpp::pp_output_iterator<_Container> &rpp::pp_output_iterator<_Container>::operator =(const char &)'
            while trying to match the argument list '(rpp::pp_output_iterator<_Container>, rpp::pp_output_iterator<_Container>)'
            C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xutility(2176) : see reference to function template instantiation '_Iter &std::_Rechecked<_OutIt,_OutIt>(_Iter &,_UIter)' being compiled
            c:\qt\qtscriptgenerator\generator\parser\rpp\pp-internal.h(83) : see reference to function template instantiation '_OutIt std::copy<std::_String_iterator<_Elem,_Traits,_Alloc>,_OutputIterator>(_InIt,_InIt,_OutIt)' being compiled
            c:\qt\qtscriptgenerator\generator\parser\rpp\pp-engine-bits.h(500) : see reference to function template instantiation 'void rpp::_PP_internal::output_line<_OutputIterator>(const std::string &,int,_OutputIterator)' being compiled
    C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xutility(275) : error C2582: 'operator =' function is unavailable in 'rpp::pp_output_iterator<_Container>'

Here's some context..



#include <algorithm>
#include <stdio.h>
namespace rpp {

namespace _PP_internal
64 template <typename _OutputIterator>
65 void output_line(const std::string &__filename, int __line, _OutputIterator __result)
66 {
67   std::string __msg;
69   __msg += "# ";
71   char __line_descr[16];
72   pp_snprintf (__line_descr, 16, "%d", __line);
73   __msg += __line_descr;
75   __msg += " \"";
77   if (__filename.empty ())
78     __msg += "<internal>";
79   else
80     __msg += __filename;
82   __msg += "\"\n";
83   std::copy (__msg.begin (), __msg.end (), __result);
84 }



#include <stdio.h>

namespace rpp {

450 template <typename _InputIterator, typename _OutputIterator>
451 void pp::operator () (_InputIterator __first, _InputIterator __last, _OutputIterator __result)
452 {
497           if (env.current_line != was)
498             {
499               env.current_line = was;
500               _PP_internal::output_line (env.current_file, env.current_line, __result);
501             }

.. and here's the definition of pp_output_iterator



#include <iterator>

namespace rpp {
template <typename _Container>
class pp_output_iterator
    : public std::iterator<std::output_iterator_tag, void, void, void, void>
    std::string &_M_result;

    explicit pp_output_iterator(std::string &__result):
    _M_result (__result) {}

    inline pp_output_iterator &operator=(typename _Container::const_reference __v)
    if (_M_result.capacity () == _M_result.size ())
        _M_result.reserve (_M_result.capacity () << 2);

    return *this;

    inline pp_output_iterator &operator * () { return *this; }
    inline pp_output_iterator &operator ++ () { return *this; }
    inline pp_output_iterator operator ++ (int) { return *this; }
like image 459
guesser Avatar asked Feb 28 '23 01:02


1 Answers

I think that the problem is that std::copy is trying to use 'copy assignment' (operator=()) on your rpp::pp_output_iterator<> and there is no operator=() for that class template. I should say, there is an operator=() but it doesn't take the correct parameter to be the 'copy assignment' function (ie., it doesn't take a ``rpp::pp_output_iterator<>&parameter). I think that the existence of someoperator=()` function will prevent the compiler from generating a default (I don't have access to the standard document at the moment to verify this 100%).

Note that a type must be assignable (among other things, of course) to be considered an OutputIterator: http://www.sgi.com/tech/stl/OutputIterator.html

Previous versions of std::copy in MSVC might not have actually used assignment (just because OutputIterator must support it doesn't mean std::copy has to use it), which is why it might be a 'new' error in VS2010. (I can't check right now due to limited access to my tools).

like image 102
Michael Burr Avatar answered Mar 07 '23 04:03

Michael Burr