C++ 当异常被禁止时分配共享的\u

C++ 当异常被禁止时分配共享的\u,c++,exception,allocator,C++,Exception,Allocator,在禁止异常(fno exceptions)且分配器返回nullptr而不是在分配失败时抛出的环境中,是否可以使用allocate\u shared?这意味着在allocate_shared周围有一个包装器,当内存分配失败时,它返回一个空的shared_ptr。我正在寻找能与GCC(libstdc++)、Clang(libc++)和MSVC一起工作的东西 当前的想法是:对控制块的大小设置一些上限,如果可以预分配足够的内存(对于控制块和对象),只调用allocate\u shared。我想,您的构造

在禁止异常(
fno exceptions
)且分配器返回
nullptr
而不是在分配失败时抛出的环境中,是否可以使用
allocate\u shared
?这意味着在
allocate_shared
周围有一个包装器,当内存分配失败时,它返回一个空的
shared_ptr
。我正在寻找能与GCC(libstdc++)、Clang(libc++)和MSVC一起工作的东西


当前的想法是:对控制块的大小设置一些上限,如果可以预分配足够的内存(对于控制块和对象),只调用
allocate\u shared

我想,您的构造函数永远不会抛出,因为您处于“无异常”环境中。同样的情况也必须适用于您的分配器。然后根据,
allocate\u shared()
将不会抛出。空的
shared_ptr
shared_ptr
完全相同,因此无需在此处创建任何包装或其他内容


所以,是的,你可以使用它,尽管我建议你尝试摆脱“无例外”的限制。我从来没有在任何地方找到这样一个限制的真正好的理由。

我想,您的构造函数从不抛出,因为您处于一个“无例外”的环境中。同样的情况也必须适用于您的分配器。然后根据,
allocate\u shared()
将不会抛出。空的
shared_ptr
shared_ptr
完全相同,因此无需在此处创建任何包装或其他内容


所以,是的,你可以使用它,尽管我建议你尝试摆脱“无例外”的限制。我从来没有在任何地方找到这样一个限制的真正好的理由。

您从文档中推断的太多了。标准分配器不应该返回
nullptr
,因此
allocate\u shared()
不能解释这种情况。实际上,您将获得非法访问,而不是一个空的
shared\u ptr
allocate\u shared()。我想,你应该确定,构造函数永远不会在空指针上被调用。那么,
allocate\u shared()
将使用
allocator\u traits::construct()
。因此,只需为您的自定义分配器专门化
allocator\u traits
,就可以了。我考虑过这样做,但根据N4140§20.8.2.2.6:
allocate\u shared
分配适合T类型对象的内存,并通过placement new表达式
:new(pv)T在该内存中构造一个对象(std::forward(args)
。尽管我认为,这在某种程度上违背了
allocator\u traits
的目的。当然
allocate\u shared()
可以通过使用
allocator\u traits::construct()来满足这一需求
,这将做一个新的放置,但我理解,这不是必需的。嗯,看起来你必须编写自己的
allocate\u shared()
变体。我认为,这是标准中的一个缺陷。实际上,即使
allocator\u traits::construct())
保证使用它是不够的。这些特性需要专门用于某些未知类型(无论库用于控制块+对象的是什么)。和
分配_共享()
仍需要了解
nullptr
情况以防止创建控制块。您从文档中推断的内容太多。标准分配器不应返回
nullptr
,因此
allocate\u shared()
不能解释这种情况。实际上,您将获得非法访问,而不是一个空的
共享\u ptr
分配\u共享()
不应该解释这种情况。我想,您应该确保构造函数永远不会在空指针上调用。嗯,
分配\u共享()
将使用
分配器\u traits::construct()
。因此,只需将
分配器特性专门化为您的自定义分配器,您就可以了。我曾想过这样做,但根据N4140§20.8.2.2.6:
分配共享
分配适合T类型对象的内存,并通过放置新表达式
::new(pv)T在该内存中构造一个对象(std::forward(args)
。尽管我认为,这在某种程度上违背了
allocator\u traits
的目的。当然
allocate\u shared()
可以通过使用
allocator\u traits::construct()来满足这一需求
,这将做一个新的放置,但我理解,这不是必需的。嗯,看起来你必须编写自己的
allocate\u shared()
变体。我认为,这是标准中的一个缺陷。实际上,即使
allocator\u traits::construct())
保证使用它是不够的。这些特征需要专门用于某些未知类型(控制块+对象使用的任何库)。而
分配共享()
仍需要了解
nullptr
情况,以防止创建控制块。