这是一个Boost错误还是我做错了什么?
#include <map>
#include <boost/pool/pool_alloc.hpp>
int main()
{
typedef const std::string key;
typedef double* (*value)(const int&);
std::map<key, value, std::less<key>> map_with_standard_allocator; // works
std::map<key, value, std::less<key>, boost::fast_pool_allocator<std::pair<const key, value> > > map_with_boost_allocator; // fails
}
最后一行无法在MS Visual Studio 2008下使用Boost 1.40和1.48进行编译。不过,它在g ++ 4.5.3(Cygwin)下编译得很好。
错误是:
1>Compiling...
1>main.cpp
1>C:\UniLib1\trunk\External\boost/pool/pool_alloc.hpp(205) : error C2535: 'const std::basic_string<_Elem,_Traits,_Ax> *boost::fast_pool_allocator<T,UserAllocator,Mutex,NextSize>::address(const std::basic_string<_Elem,_Traits,_Ax> &)' : member function already defined or declared
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>,
1> T=const std::basic_string<char,std::char_traits<char>,std::allocator<char>>,
1> UserAllocator=boost::default_user_allocator_new_delete,
1> Mutex=boost::details::pool::default_mutex,
1> NextSize=32
1> ]
1> C:\UniLib1\trunk\External\boost/pool/pool_alloc.hpp(202) : see declaration of 'boost::fast_pool_allocator<T,UserAllocator,Mutex,NextSize>::address'
1> with
1> [
1> T=const std::basic_string<char,std::char_traits<char>,std::allocator<char>>,
1> UserAllocator=boost::default_user_allocator_new_delete,
1> Mutex=boost::details::pool::default_mutex,
1> NextSize=32
1> ]
1> c:\Program Files\Microsoft Visual Studio 9.0\VC\include\xtree(137) : see reference to class template instantiation 'boost::fast_pool_allocator<T,UserAllocator,Mutex,NextSize>' being compiled
1> with
1> [
1> T=const std::basic_string<char,std::char_traits<char>,std::allocator<char>>,
1> UserAllocator=boost::default_user_allocator_new_delete,
1> Mutex=boost::details::pool::default_mutex,
1> NextSize=32
1> ]
1> c:\Program Files\Microsoft Visual Studio 9.0\VC\include\map(78) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled
1> with
1> [
1> _Traits=std::_Tmap_traits<key,value ,std::less<key>,boost::fast_pool_allocator<std::pair<key,value >>,false>
1> ]
1> .\main.cpp(9) : see reference to class template instantiation 'std::map<_Kty,_Ty,_Pr,_Alloc>' being compiled
1> with
1> [
1> _Kty=key,
1> _Ty=value,
1> _Pr=std::less<key>,
1> _Alloc=boost::fast_pool_allocator<std::pair<key,value >>
1> ]
答案 0 :(得分:1)
这不是VS2008中的错误(因为我在此答案的早期编辑中错误地声称)。 C ++ 03标准要求关联容器的密钥类型(如std::map
)必须是“可分配的”(根据23.1.2“关联容器”中的表69)。并且const std::string
不可分配。请注意,C ++ 11标准似乎放宽了这一要求,但自VC ++ 2008起,新标准不适用。
我不清楚是否需要编译器来诊断尝试将std::map
与不可分配密钥一起使用的代码,因此我认为不能声称GCC或VC ++ 2010正在接受此代码不正确(我认为它属于未定义代码的区域,按照您的预期工作,即使不能保证它也能正常工作)。但很明显VC ++ 2008拒绝编译它是可以的。
所有这一切,我认为VC ++ 2008的库在地图的键而不是map的元素上参数化分配器的address()
函数仍然是可疑的(如果你感兴趣的话,请参阅这个答案的第一个编辑细节),但我不认为那里有任何真正的错误,因为用于保存地图元素的std::pair<>
将始终设置为使得关键部分与整个元素位于同一地址。