4

我正在尝试使用 Visual Studio 2010 (C++) 编译 QtScriptGenerator ( gitorious ) 并遇到编译错误。在寻找解决方案时,我偶尔会看到由于 VS2010 的 STL 实现和/或 c++0x 一致性更改而导致的自 VS2008 以来引入的编译损坏的引用。

任何想法下面发生了什么,或者我该如何解决它?如果有问题的代码似乎是 QtScriptGenerator 的,我想我会更容易修复它。但在我看来,有问题的代码可能在 VS2010 的 STL 实现中,我可能需要创建一个解决方法?

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
            ]

这是一些上下文..

pp-内部.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 }

pp-engine-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的定义

pp-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; }
};
4

3 回答 3

5

我认为问题在于std::copy尝试operator=()在您的身上使用“复制作业”(),而该类模板rpp::pp_output_iterator<>没有。operator=()我应该说,有一个operator=()但它没有将正确的参数作为“复制分配”函数(即,它不需要 ``rpp::pp_output_iterator<>& parameter). I think that the existence of someoperator=()` 函数将防止编译器生成默认值(我目前无权访问标准文档来验证这 100%)。

请注意,类型必须是可分配的(当然,除其他外)才能被视为 OutputIterator:http ://www.sgi.com/tech/stl/OutputIterator.html

MSVC 中的早期版本std::copy可能没有实际使用赋值(仅仅因为 OutputIterator 必须支持它并不意味着std::copy必须使用它),这就是为什么它可能是 VS2010 中的“新”错误。(由于对我的工具的访问受限,我现在无法检查)。

于 2010-05-08T04:35:46.670 回答
2

这些代码添加到模板类 pp_output_iterator 的 pp-iterator.h 中,并且可以解决此问题:

  inline pp_output_iterator &operator=(const typename pp_output_iterator<_Container>& __v)
  {
    _M_result = __v._M_result;
    return *this;
  }
于 2011-10-23T08:51:19.783 回答
1

我有同样的问题。猜测者在这里所说的事情对我来说对我从 git 存储库(4.7.2011)获得的代码没有多大意义,所以我以另一种方式解决了这个问题。

此问题仅存在于生成器项目中,该生成器生成生成器,该生成器生成由 qtbindings 项目使用的生成代码。简单的事实是您不必使用 VC10 来构建生成器,您可以使用 Qt 提供的 VC9 构建来制作生成器,这不会产生 OP 提到的构建错误。

在运行生成器之前:请记住将 QTDIR 更改为您想要绑定的 VC10 Qt 版本,或者我想如果版本号相同,那无论如何都无关紧要。generator.exe 将构建在发布文件夹中,将其以及 QtCore 和 QtXml dll:s 从您构建生成器的 VC9 Qt 复制到父文件夹。

在此之后使用 VC10 构建 qtbindings 项目。我在那里遇到了一些小问题,比如它的链接器输出扩展名为 .lib,只需将所有这些更改为 .dll 就可以了。

希望这可以帮助人们,如果他们在未来遇到这个问题,因为 Visual Studio 10 获得更多的牵引力:) 希望维护者能在某个时候修复构建错误。

于 2011-07-04T01:21:08.220 回答