我正在尝试使用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
]
这是一些背景信息..
#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 }
#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
的定义#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; }
};
答案 0 :(得分:5)
我认为问题在于std::copy
正试图在operator=()
上使用'版权分配'(rpp::pp_output_iterator<>
)而该类模板没有operator=()
。我应该说,有一个operator=()
,但它不会将正确的参数作为'复制赋值'函数(即,它不需要``rpp :: pp_output_iterator&lt;&gt;&amp; parameter). I think that the existence of some
operator =()`函数将阻止编译器生成默认值(我目前无法访问标准文档来验证此100%)。
请注意,类型必须是可分配的(当然,除其他外),才能被视为OutputIterator:http://www.sgi.com/tech/stl/OutputIterator.html
MSVC中以前版本的std::copy
可能没有实际使用过赋值(只是因为OutputIterator必须支持它并不意味着std::copy
必须使用它),这就是为什么它可能是'新的'VS2010中的错误。 (由于访问我的工具的限制,我现在无法检查。)
答案 1 :(得分:2)
我将这些代码添加到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;
}
答案 2 :(得分:1)
我有同样的问题。对于我从git repo(从4.7.2011开始)获得的代码,我在这里说的话对我没有多大意义,所以我以另一种方式解决了这个问题。
此问题仅出现在生成项目的生成器项目中,该生成器生成qtbindings项目使用的生成代码。简单的事实是你不必使用VC10来构建生成器,你可以使用Qt提供的VC9构建来使这个生成器不会产生OP提到的构建错误。
在运行生成器之前:记得将QTDIR更改为您想要绑定的VC10 Qt构建,或者我想如果版本号相同则无关紧要。 generator.exe将构建在release文件夹中,将QtCore和QtXml dll:s复制到您构建生成器的VC9 Qt的父文件夹中。
用VC10构建qtbindings项目之后。我有一些小问题,例如它有链接器输出扩展名为.lib,只需将所有这些更改为.dll,它应该会低谷。
希望这可以帮助人们,如果他们将来有这方面的Probs,因为Visual Studio 10获得更多的牵引力:)希望维护者将在某些时候修复构建错误。