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

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

I added these code to pp-iterator.h for template class pp_output_iterator, and can fix this issue:

  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 に答える