我有一些C ++代码因编译错误而失败,除非它在C ++ 11模式下运行,但我无法弄清楚为什么会出现这种情况,因为代码没有(明确地)使用C ++ 11功能:
#include <vector>
#include <map>
#include <boost/unordered_map.hpp>
struct SomeStruct {
boost::unordered_map<int, int> intMap;
};
int main(int argc, const char* argv[]) {
std::vector<SomeStruct> vals;
vals.resize(100);
}
在使用gcc 4.6.3-1ubuntu5和boost 1.48的Ubuntu 12.04 64位机器上编译时:
g++ test.cpp
然后我得到了这个编译错误:
In file included from /usr/include/c++/4.6/vector:61:0,
from test.cpp:1:
/usr/include/c++/4.6/bits/stl_algobase.h: In function 'typename __gnu_cxx::__enable_if<(! std::__is_scalar<_Tp>::__value), void>::__type std::__fill_a(_ForwardIterator, _ForwardIterator, const _Tp&) [with _ForwardIterator = SomeStruct*, _Tp = SomeStruct, typename __gnu_cxx::__enable_if<(! std::__is_scalar<_Tp>::__value), void>::__type = void]':
/usr/include/c++/4.6/bits/stl_algobase.h:722:7: instantiated from 'void std::fill(_ForwardIterator, _ForwardIterator, const _Tp&) [with _ForwardIterator = SomeStruct*, _Tp = SomeStruct]'
/usr/include/c++/4.6/bits/vector.tcc:397:5: instantiated from 'void std::vector<_Tp, _Alloc>::_M_fill_insert(std::vector<_Tp, _Alloc>::iterator, std::vector<_Tp, _Alloc>::size_type, const value_type&) [with _Tp = SomeStruct, _Alloc = std::allocator<SomeStruct>, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<SomeStruct*, std::vector<SomeStruct> >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = SomeStruct*, std::vector<_Tp, _Alloc>::size_type = long unsigned int, std::vector<_Tp, _Alloc>::value_type = SomeStruct]'
/usr/include/c++/4.6/bits/stl_vector.h:944:9: instantiated from 'void std::vector<_Tp, _Alloc>::insert(std::vector<_Tp, _Alloc>::iterator, std::vector<_Tp, _Alloc>::size_type, const value_type&) [with _Tp = SomeStruct, _Alloc = std::allocator<SomeStruct>, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<SomeStruct*, std::vector<SomeStruct> >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = SomeStruct*, std::vector<_Tp, _Alloc>::size_type = long unsigned int, std::vector<_Tp, _Alloc>::value_type = SomeStruct]'
/usr/include/c++/4.6/bits/stl_vector.h:632:4: instantiated from 'void std::vector<_Tp, _Alloc>::resize(std::vector<_Tp, _Alloc>::size_type, std::vector<_Tp, _Alloc>::value_type) [with _Tp = SomeStruct, _Alloc = std::allocator<SomeStruct>, std::vector<_Tp, _Alloc>::size_type = long unsigned int, std::vector<_Tp, _Alloc>::value_type = SomeStruct]'
test.cpp:12:18: instantiated from here
/usr/include/c++/4.6/bits/stl_algobase.h:676:2: error: no match for 'operator=' in '* __first = __value'
/usr/include/c++/4.6/bits/stl_algobase.h:676:2: note: candidate is:
test.cpp:5:8: note: SomeStruct& SomeStruct::operator=(SomeStruct&)
test.cpp:5:8: note: no known conversion for argument 1 from 'const SomeStruct' to 'SomeStruct&'
在gcc中启用C ++ 11支持时编译很好:
g++ -std=c++0x test.cpp
有人可以解释为什么这只适用于C ++ 11模式吗?
修改
使用Vagrant重现的步骤:
vagrant init precise64
vagrant up
vagrant ssh
sudo apt-get install -y build-essential libboost1.48-all-dev
echo "#include <vector>
#include <map>
#include <boost/unordered_map.hpp>
struct SomeStruct {
boost::unordered_map<int, int> intMap;
};
int main(int argc, const char* argv[]) {
std::vector<SomeStruct> vals;
vals.resize(100);
}" > test.cpp
g++ test.cpp
答案 0 :(得分:3)
boost::unordered_map
的复制赋值运算符声明为:
unordered_map& operator=(unordered_map &t)
反过来导致(C ++ 98 12.8 [#10])SomeStruct
的隐式复制赋值运算符被声明为:
SomeStruct &operator= (SomeStruct &);
添加显式的复制赋值运算符
SomeStruct &operator= (const SomeStruct &x) { intMap = x.intMap; return *this; }
解决了这个问题,它通过调用unordered_map::operator=
的不同重载来实现。
此问题已在Boost 1.52中修复。它将运算符声明为:
unordered_map& operator=(unordered_map const& x);