编辑:
澄清我期望的结果,因为我没有很好地传达它:
能够使用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, (__gnu_cxx :: _ Lock_policy)2U&GT; :: _ Sp_counted_ptr_inplace(常量 的std :: _ Sp_counted_ptr_inplace, (__gnu_cxx :: _ Lock_policy)2U&GT;&安培)” {new(ptr)T(t); } ^
/ usr / include / c ++ / 4.8 / bits / shared_ptr_base.h:198:错误: “的std :: _ Sp_counted_base&LT; _Lp&GT; :: _ Sp_counted_base(常量 std :: _ Sp_counted_base&lt; _Lp&gt;&amp;)[with __gnu_cxx :: _ Lock_policy _Lp = (__gnu_cxx :: _ Lock_policy)2u]'是私有的 _Sp_counted_base(_Sp_counted_base const&amp;)=删除; ^ /usr/include/c++/4.8/bits/shared_ptr_base.h:379:错误:在此内 上下文 class _Sp_counted_ptr_inplace final:public _Sp_counted_base&lt; _Lp&gt; ^
/ usr / include / c ++ / 4.8 / bits / shared_ptr_base.h:379:错误:使用已删除 function'std :: _ Sp_counted_base&lt; _Lp&gt; :: _ Sp_counted_base(const std :: _ Sp_counted_base&lt; _Lp&gt;&amp;)[with __gnu_cxx :: _ Lock_policy _Lp = (__gnu_cxx :: _ Lock_policy)2U]”
/ usr / include / c ++ / 4.8 / bits / shared_ptr_base.h:198:错误:在这里声明 _Sp_counted_base(_Sp_counted_base const&amp;)=删除; ^
4.9 - 讨厌的编译错误(略有不同)
/XXXXXXXXXXX/boost/boost/pool/pool_alloc.hpp:399:错误:使用 删除函数'std :: _ Sp_counted_ptr_inplace, (__gnu_cxx :: _ Lock_policy)2U&GT; :: _ Sp_counted_ptr_inplace(常量 的std :: _ Sp_counted_ptr_inplace, (__gnu_cxx :: _ Lock_policy)2U&GT;&安培)” {new(ptr)T(t); } ^
/ usr / include / c ++ / 4.9 / bits / shared_ptr_base.h:203:错误: “的std :: _ Sp_counted_base&LT; _Lp&GT; :: _ Sp_counted_base(常量 std :: _ Sp_counted_base&lt; _Lp&gt;&amp;)[with __gnu_cxx :: _ Lock_policy _Lp = (__gnu_cxx :: _ Lock_policy)2u]'是私有的 _Sp_counted_base(_Sp_counted_base const&amp;)=删除; ^
/ usr / include / c ++ / 4.9 / bits / shared_ptr_base.h:494:错误:在此内 上下文 class _Sp_counted_ptr_inplace final:public _Sp_counted_base&lt; _Lp&gt; ^
/ usr / include / c ++ / 4.9 / bits / shared_ptr_base.h:494:错误:使用已删除 function'std :: _ Sp_counted_base&lt; _Lp&gt; :: _ Sp_counted_base(const std :: _ Sp_counted_base&lt; _Lp&gt;&amp;)[with __gnu_cxx :: _ Lock_policy _Lp = (__gnu_cxx :: _ Lock_policy)2u]'
我花了很多钱 时间试图找到这个底部,我会得到一些帮助 如果有人更熟悉其内部运作,我们将不胜感激 这些组件。
答案 0 :(得分:3)
我花了很多时间查看不同的编译器版本,假设这是一个编译器错误,如g ++ 4.7中的崩溃和其他回答者/评论者的评论所暗示的那样。然而,在回到编译错误并挖掘它们一段时间之后,我设法最终以一定程度的特异性理解编译错误的原因。
所以这个问题确实存在于boost::fast_pool_allocator
和boost::pool_allocator
中,回想起来似乎有点明显。问题的基本关键是boost allocators construct method是根据c ++ 98标准分配器规范实现的,并且有一个构造方法,它采用单个const&amp; param用于复制构造新的位置对象。 c ++ 11样式使用可变参数模板,并且args被传递给通过placement new创建的对象的构造函数。在我的测试代码的特定情况下,它是不会将初始化值传递给导致错误的std::allocate_shared
的变体。手头的核心问题是c ++ 11 std::allocate_shared
试图将可变数量的参数传递给只需要一个的construct()
方法。在我的测试中,当传入一个值时,我可以断开构造方法,并且不会为其他变体调用它。例如,如果要分配std::pair<>
(2个参数),则根本不调用构造方法,并且必须使用其他一些机制。我对此进行了一些跟踪,看起来std::allocate_shared
在内部包装了构造调用,如果对构造的调用没有匹配,则调用另一个方法(通过隐式函数查找)直接构造对象。下面的top方法调用分配器的construct()
方法,最下面的方法直接调用对象:
alloc_traits.h:250-61
template<typename _Tp, typename... _Args>
static typename
enable_if<__construct_helper<_Tp, _Args...>::value, void>::type
_S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
{ __a.construct(__p, std::forward<_Args>(__args)...); }
template<typename _Tp, typename... _Args>
static typename
enable_if<__and_<__not_<__construct_helper<_Tp, _Args...>>,
is_constructible<_Tp, _Args...>>::value, void>::type
_S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
{ ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); }
这是我有时间真正确定编译错误的来源,但这足以让我为这个问题整理一个简单而有效的解决方案。
这里的解决方案很简单;需要更新boost以使用新的c ++ 11分配器规范。这样做实际上非常简单;在pool_alloc.hpp中替换所有实例:
void construct(const pointer ptr, const value_type & t)
{ new (ptr) T(t); }
与
template <typename... Args>
void construct(const pointer ptr, Args&&... args)
{
new (ptr) T( std::forward<Args>(args)... );
}
似乎这是一个错误,提升没有更新他们的代码用于c ++ 11支持,但事实上g ++ 5.0(我确认)编译没有问题意味着添加此支持不是必须的向前。可能是std::allocate_shared
旨在向后兼容旧的分配器接口,4.7,4.8和4.9的崩溃和编译错误是支持被破坏。我将在增强错误跟踪器上发布一张票,看看他们认为这笔交易是什么:boost trac ticket
答案 1 :(得分:2)
由于这似乎是libstdc ++的一个问题(?),您可以使用标准库函数的boost等效代替boost::allocate_shared
。包括<boost/make_shared.hpp>
。这是一个 Coliru demo ,显示了四个不同的GCC版本,可以正常编译。正如我在评论中提到的,std::allocate_shared
适用于GCC的主干版本和libc ++。我无法找到与此问题相关的现有错误报告,但您可以为GCC或Boost提交一个。