4

これはブーストのバグですか、それとも何か間違っていますか?

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

最後の行は、Boost 1.40 および 1.48 を使用する MS Visual Studio 2008 でコンパイルできません。ただし、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>        ]
4

1 に答える 1

1

これは VS2008 のバグではありません (この回答の以前の編集で誤って主張したため)。C++03 標準では、 のような連想コンテナのキー タイプはstd::map「割り当て可能」でなければなりません (23.1.2「連想コンテナ」の表 69 による)。そして aconst std::stringは代入できません。C++11 標準ではこの要件が緩和されているようですが、新しい標準は VC++ 2008 以降には適用されないことに注意してください。

割り当て不可能なキーを使用しようとするコードを診断するためにコンパイラが必要であることは明らかではstd::mapないため、GCC または VC++ 2010 がこのコードを不適切に受け入れていると主張することはできないと思います (動作する保証はありませんが、期待どおりに動作する未定義のコードの領域)。ただし、VC++ 2008 がコンパイルを拒否しても問題ないことは明らかです。

そうは言ってaddress()も、マップの要素ではなくマップのキーでアロケーターの関数をパラメーター化するVC++ 2008のライブラリはまだ疑わしいと思います(興味がある場合は、詳細についてこの回答の最初の編集を参照してください)が、何もないと思いますstd::pair<>マップ要素を保持するために使用される は、キー部分が要素全体と同じアドレスになるように常に設定されるため、実際のバグがあります。

于 2012-05-11T16:04:59.613 に答える