Оператор STL = изменение поведения в Visual Studio 2010? - PullRequest
4 голосов
/ 08 мая 2010

Я пытаюсь скомпилировать QtScriptGenerator ( gitorious ) с Visual Studio 2010 (C ++) и столкнулся с ошибкой компиляции. В поисках решения я видел случайные ссылки на сбои компиляции, появившиеся после VS2008 из-за изменений в реализации STL и / или c ++ 0x в VS2010.

Есть идеи, что происходит ниже, или как я могу исправить это? Если нарушающий код оказался QtScriptGenerator, я думаю, мне было бы легче его исправить ... но мне кажется, что нарушающий код может быть в реализации STL VS2010 и мне может потребоваться создать обходной путь?

PS. Я довольно незнаком с шаблонами и STL. У меня есть опыт работы со встроенными и консольными проектами, где до недавнего времени таких вещей часто избегали, чтобы уменьшить потребление памяти и риски кросс-компиляции.

Редактировать - Похоже, что это - реализация Visual Studio std :: copy , которая изменилась.

    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)
            with
            [
                _Container=std::string
            ]
            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 &)'
            with
            [
                _Container=std::string
            ]
            while trying to match the argument list '(rpp::pp_output_iterator<_Container>, rpp::pp_output_iterator<_Container>)'
            with
            [
                _Container=std::string
            ]
            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
            with
            [
                _Iter=rpp::pp_output_iterator<std::string>,
                _OutIt=rpp::pp_output_iterator<std::string>,
                _UIter=rpp::pp_output_iterator<std::string>
            ]
            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
            with
            [
                _OutIt=rpp::pp_output_iterator<std::string>,
                _Elem=char,
                _Traits=std::char_traits<char>,
                _Alloc=std::allocator<char>,
                _OutputIterator=rpp::pp_output_iterator<std::string>,
                _InIt=std::_String_iterator<char,std::char_traits<char>,std::allocator<char>>
            ]
            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
            with
            [
                _OutputIterator=rpp::pp_output_iterator<std::string>
            ]
    C:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xutility(275) : error C2582: 'operator =' function is unavailable in 'rpp::pp_output_iterator<_Container>'
            with
            [
                _Container=std::string
            ]

Вот некоторый контекст ..

рр-internal.h

#ifndef PP_INTERNAL_H
#define PP_INTERNAL_H

#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;
68 
69   __msg += "# ";
70 
71   char __line_descr[16];
72   pp_snprintf (__line_descr, 16, "%d", __line);
73   __msg += __line_descr;
74 
75   __msg += " \"";
76 
77   if (__filename.empty ())
78     __msg += "<internal>";
79   else
80     __msg += __filename;
81 
82   __msg += "\"\n";
83   std::copy (__msg.begin (), __msg.end (), __result);
84 }

С.-двигатель-bits.h

#ifndef PP_ENGINE_BITS_H
#define PP_ENGINE_BITS_H

#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             }

.. и вот определение pp_output_iterator

С.-iterator.h

#ifndef PP_ITERATOR_H
#define PP_ITERATOR_H

#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;

public:
    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);

    _M_result.push_back(__v);
    return *this;
    }

    inline pp_output_iterator &operator * () { return *this; }
    inline pp_output_iterator &operator ++ () { return *this; }
    inline pp_output_iterator operator ++ (int) { return *this; }
};

Ответы [ 3 ]

5 голосов
/ 08 мая 2010

Я думаю, что проблема в том, что std::copy пытается использовать «назначение копии» (operator=()) на вашем rpp::pp_output_iterator<>, и для этого шаблона класса нет operator=(). Я должен сказать, что есть operator=(), но он не принимает правильный параметр, чтобы быть функцией «копирования» (т. Е. Он не принимает оператор `` rpp :: pp_output_iterator <> & parameter). I think that the existence of some) = () `функция не даст компилятору сгенерировать значение по умолчанию (в настоящий момент у меня нет доступа к стандартному документу, чтобы проверить это на 100%).

Обратите внимание, что тип должен быть назначаемым (помимо прочего, конечно), чтобы считаться OutputIterator: http://www.sgi.com/tech/stl/OutputIterator.html

Предыдущие версии std::copy в MSVC могли фактически не использовать назначение (только потому, что OutputIterator должен поддерживать это, не означает, что std::copy должно использовать его), поэтому это может быть «новой» ошибкой в ​​VS2010 , (Я не могу проверить сейчас из-за ограниченного доступа к моим инструментам).

2 голосов
/ 23 октября 2011

I добавил этот код в pp-iterator.h для класса шаблона pp_output_iterator и может решить эту проблему:

  inline pp_output_iterator &operator=(const typename pp_output_iterator<_Container>& __v)
  {
    _M_result = __v._M_result;
    return *this;
  }
1 голос
/ 04 июля 2011

У меня была такая же проблема. То, что гадатель говорит здесь, не имело для меня большого смысла в отношении кода, который я получил из репозитория git (глава 4.7.2011), поэтому я обошел это по-другому.

Эта проблема существует только в проекте генератора, который создает генератор, который создает сгенерированный код, который используется проектом qtbindings. Простой факт заключается в том, что вам не нужно использовать VC10 для сборки генератора, вы можете использовать Qt при условии сборки VC9, чтобы сделать генератор, который не будет вызывать упомянутые ошибки сборки OP.

Перед запуском генератора: не забудьте изменить QTDIR на сборку VC10 Qt, с которой вы хотите связать, или я думаю, что в любом случае это не имеет значения, если номер версии совпадает. Generator.exe будет встроен в папку выпуска, скопируйте его и QtCore и QtXml dll: s в родительскую папку из вашего VC9 Qt, для которого вы создали генератор.

После этого соберите проект qtbindings с VC10. У меня были некоторые незначительные проблемы, такие как расширение выходных данных компоновщика как .lib, просто измените все на .dll, и все должно пройти.

Надеюсь, что это поможет людям, если у них появятся пробники с этим в будущем, поскольку Visual Studio 10 получит больше возможностей :) Надеемся, что сопровождающие исправят ошибку сборки в какой-то момент.

...