C++11是否要求分配器必须是默认可构造的,libstdc++和libc++存在分歧?

13

使用稍加修改的Howard Hinnant 的 C++11 栈分配器文档在此这里,加上 std::basic_string 并使用编译器 gcclibstdc++,以下代码示例(在线演示):

const unsigned int N = 200;

arena<N> a;
short_alloc<char, N> ac(a) ;

std::basic_string<char,std::char_traits<char>,short_alloc<char, N>> empty(ac);

会产生以下错误(等等):

error: no matching function for call to 'short_alloc<char, 200ul>::short_alloc()'
   if (__n == 0 && __a == _Alloc())
                       ^

然而,当使用clang并且使用libc++请参考实例),它可以正常编译而没有错误。

std::basic_stringstdlibc++实现期望分配器具有默认构造函数。

C++11是否要求分配器具有默认构造函数?哪种实现是正确的?


2
自问自答的问题会自动获得负分。我知道是谁干的,但没有证据。不管怎么样,他们需要承受这个,因为自问自答的政策(它明确地被鼓励,并且甚至有GUI选项!!)已经与他们联系多次,但他们似乎无法接受。 - Lightness Races in Orbit
1个回答

12
不,根据C++11标准草案第17.6.3.5节[allocator.requirements]中的表格28 Allocator requirements,C++11不要求分配器具有默认构造函数。同时,在该节中提供了最小符合接口的示例,其中没有要求默认构造函数。
template <class Tp>
struct SimpleAllocator {
    typedef Tp value_type;
    SimpleAllocator(ctor args );

    template <class T> SimpleAllocator(const SimpleAllocator<T>& other);

    Tp *allocate(std::size_t n);
    void deallocate(Tp *p, std::size_t n);
};

— 结束示例]

该类不包含默认构造函数。

有一个 libstdc++ 的错误报告:basic_string 假设分配器具有默认构造函数,其内容如下:

basic_string 的空字符串优化假定分配器具有默认构造函数。尽管在 C++98 中曾经是这样,但在 C++11 中不再是这样,因为现在允许分配器具有状态。

请考虑附带的示例程序。使用以下命令进行编译:

g++ -std=c++11 -c t.cpp

尽管本应编译通过,但会产生错误信息。问题在于"_S_construct"调用了不存在的"_Alloc()"。

请注意,C++11标准不要求默认构造函数 (第17.6.3.5节,表28)。特别是来自第17.6.3.5节的SimpleAllocator示例也会触发同样的 bug。

这不仅是 std::string 中缺失的唯一的 C++11 分配器要求,所有新要求都被省略了,直到我们切换到非 COW 字符串实现才可能实现。

这个问题已经在 gcc 5.0中得到解决:

已在 GCC 5 中修复(使用新字符串 ABI)。

我们可以使用 wandbox 上的 gcc 5 来确认这一点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接