编辑:
澄清我期望的结果,因为我没有很好地传达它:
能够使用 std::allocate_shared
和 boost::fast_pool_allocator
作为分配方法,使用g 4.8或更高版本,使用boost 1.56.0 . 目前这适用于g 4.6,并且在4.7,4.8和4.9上失败 .
要明确的是,我不打算为g 4.7做这项工作 .
测试代码产生错误:
#include "boost/pool/pool.hpp"
#include "boost/pool/pool_alloc.hpp"
#include <memory>
int main(int argc, char** argv)
{
auto fails = std::allocate_shared<int>( boost::fast_pool_allocator<int>() );
auto works = std::allocate_shared<int>(boost::fast_pool_allocator<int>(), 5);
}
在我们的代码库中,我们将std :: allocate_shared与boost池分配器结合使用,这会导致一些讨厌的编译错误 . 然而,这已经在不同版本的g中变形和变化:
详情:64bit,(4.7,4.8)-std = c 11,(4.6)-std = c 0x,boost 1.56.0
4.6 - 愉快地编译
4.7 - 崩溃编译器
内部编译器错误:重新输入错误报告例程 . 如果合适,请提交完整的错误报告,并提供预处理的来源 . 请参阅说明 . 存储在/tmp/cca0Emq9.out文件中的预处理源,请将其附加到您的bug报告中 .
4.8 - 令人讨厌的编译错误
/XXXXXXXXXX/boost/boost/pool/pool_alloc.hpp:399:
错误:使用已删除的函数'std :: _ Sp_counted_ptr_inplace,(__ gn_cxx :: _ Lock_policy)2u> :: _ Sp_counted_ptr_inplace(const std :: _ Sp_counted_ptr_inplace,(__ gn_cxx :: _ Lock_policy)2u>&)'{new(ptr)T(t) ; } ^ / usr / include / c /4.8/bits/shared_ptr_base.h:198:错误:'std :: _ Sp_counted_base <_Lp> :: _ Sp_counted_base(const std :: _ Sp_counted_base <_Lp>&)[与__gnu_cxx :: _ Lock_policy Lp =(_ nuu_cxx :: _ Lock_policy)2u]'是私有的_Sp_counted_base(_Sp_counted_base const&)= delete; ^ / usr / include / c /4.8/bits/shared_ptr_base.h:379:错误:在此上下文类_Sp_counted_ptr_inplace final:public _Sp_counted_base <_Lp> ^ / usr / include / c /4.8/bits/shared_ptr_base.h:379:错误:使用已删除的函数'std :: _ Sp_counted_base <_Lp> :: _ Sp_counted_base(const std :: _ Sp_counted_base <_Lp>&)[与__gnu_cxx :: _ Lock_policy Lp =(_ nuu_cxx :: _ Lock_policy)2u]'/ usr / include / c /4.8/bits/shared_ptr_base.h:198:错误:此处声明_Sp_counted_base(_Sp_counted_base const&)= delete; ^
4.9 - 令人讨厌的编译错误(略有不同)
/XXXXXXXXXXX/boost/boost/pool/pool_alloc.hpp:399:错误:使用已删除的函数'std :: _ Sp_counted_ptr_inplace,(__ gn_cxx :: _ Lock_policy)2u> :: _ Sp_counted_ptr_inplace(const std :: _ Sp_counted_ptr_inplace,(__ nuu_cxx ::) _Lock_policy)2u>&)'{new(ptr)T(t); } ^ / usr / include / c /4.9/bits/shared_ptr_base.h:203:错误:'std :: _ Sp_counted_base <_Lp> :: _ Sp_counted_base(const std :: _ Sp_counted_base <_Lp>&)[与__gnu_cxx :: _ Lock_policy Lp =(_ nuu_cxx :: _ Lock_policy)2u]'是私有的_Sp_counted_base(_Sp_counted_base const&)= delete; ^ / usr / include / c /4.9/bits/shared_ptr_base.h:494:错误:在此上下文类_Sp_counted_ptr_inplace final:public _Sp_counted_base <_Lp> ^ / usr / include / c /4.9/bits/shared_ptr_base.h:494:错误:使用已删除的函数'std :: _ Sp_counted_base <_Lp> :: _ Sp_counted_base(const std :: _ Sp_counted_base <_Lp>&)[与__gnu_cxx :: _ Lock_policy Lp =(_ nuu_cxx :: _ Lock_policy)2u]'
我花了很多时间试图深入研究这个问题,如果有人更熟悉这些组件的内部工作原理,我会感激不尽 .
2 回答
我花了很多时间查看不同的编译器版本,假设这是一个编译器错误,如g 4.7中的崩溃和其他回答者/评论者的评论所示 . 然而,在回到编译错误并挖掘它们一段时间之后,我设法最终以一定程度的特异性理解编译错误的原因 .
所以问题确实存在于
boost::fast_pool_allocator
和boost::pool_allocator
中,回想起来似乎有点明显 . 问题的基本症结在于,boost allocators construct method是根据c 98标准分配器规范实现的,并且有一个构造方法,该方法采用单个const&param来复制构造new的对象 . c 11样式使用可变参数模板,并且args被传递给通过placement new创建的对象的构造函数 . 在我的测试代码的特定情况下,它是不会将初始化值传递给导致错误的std::allocate_shared
的变体 . 手头的核心问题是c 11std::allocate_shared
试图将可变数量的参数传递给只需要一个的construct()
方法 . 在我的测试中,当传入一个值并且没有为其他值调用时,我可以断开构造方法变种 . 例如,如果要分配std::pair<>
(2参数),则根本不调用构造方法,并且必须使用其他一些机制 . 我跟踪了一下这看起来像std::allocate_shared
在内部包装了构造调用,如果对构造的调用不匹配,则调用另一个方法(通过隐式函数查找)直接构造对象 . 下面的top方法调用分配器的construct()
方法,底层的新方法直接调用对象:alloc_traits.h:250-61
这是我有时间去确定编译错误的来源,但这足以让我为这个问题整理一个简单而有效的解决方案 .
这里的解决方案很简单;需要更新boost以使用新的c 11分配器规范 . 这样做实际上非常简单;在pool_alloc.hpp中替换所有实例:
同
似乎这是一个错误,提升没有更新他们的代码以获得c 11支持,但事实上g 5.0(我确认)编译没有问题意味着添加此支持不是强制性的 . 可能是
std::allocate_shared
旨在向后兼容旧的分配器接口,4.7,4.8和4.9的崩溃和编译错误是支持被破坏 . 我将在增强错误跟踪器上发布一张票,看看他们认为这笔交易是什么:boost trac ticket由于这似乎是libstdc的一个问题(?),你可以使用标准库函数的boost等效而不是boost::allocate_shared . 包括
<boost/make_shared.hpp>
. 这是一个 Coliru demo ,显示四个不同的GCC版本编译正常 . 正如我在评论中提到的,std::allocate_shared
适用于GCC的主干版本和libc . 我无法找到与此问题相关的现有错误报告,但您可以为GCC或Boost提交一个 .