带有std :: basic_string<>的C ++ 11有状态分配器g ++ 6.3.0

时间:2017-07-08 07:48:52

标签: c++ c++11

我试图让C ++ 11分配器使用std :: basic_string<>。我的代码看起来像这样(这是一个最小的例子)。我遇到的问题是它适用于Xcode,类似的东西适用于Visual Studio,但我无法在g ++上编译它。我使用的是g ++ 6.3.0,我尝试过-D_GLIBCXX_USE_CXX11_ABI = 1和-D_GLIBCXX_USE_CXX11_ABI = 0

#include <stdio.h>
#include <iostream>
#include <string>

template <class TYPE> class my_allocator
    {
    public:
        int instance;

    public:
        using value_type = TYPE;

        my_allocator(int val) : instance(val) { }
        my_allocator(const my_allocator<TYPE> &other) : instance(other.instance) { }

        bool operator==(const my_allocator<TYPE> &that) const { return instance == that.instance; }
        bool operator!=(const my_allocator<TYPE> &that) const { return instance != that.instance; }

        TYPE *allocate(const size_t number)
            {
            if (number == 0)
                return nullptr;

            if (number > (size_t)-1 / sizeof(TYPE))
                throw std::bad_array_new_length();

            TYPE *pointer = (TYPE *)::malloc(number * sizeof(TYPE));

            if (pointer == nullptr)
                throw std::bad_alloc();

            return pointer;
            }

        void deallocate(TYPE * const pointer, size_t number) const { free(pointer); }
    };

typedef std::basic_string<char, std::char_traits<char>, my_allocator<char>>my_string;

int main(void)
    {
    my_allocator<char> allocator(1);

    my_string str(allocator);
    str = "one";
    std::cout << str;

    return 0;
    }

我不明白的是错误开始了:

In file included from /usr/include/c++/6/string:52:0,
                 from /usr/include/c++/6/bits/locale_classes.h:40,
                 from /usr/include/c++/6/bits/ios_base.h:41,
                 from /usr/include/c++/6/ios:42,
                 from /usr/include/c++/6/ostream:38,
                 from /usr/include/c++/6/iostream:39,
                 from broken.cpp:6:
/usr/include/c++/6/bits/basic_string.h: In instantiation of ‘class std::basic_string<char, std::char_traits<char>, my_allocator<char> >’:
broken.cpp:49:25:   required from here
/usr/include/c++/6/bits/basic_string.h:2616:63: error: no class template named ‘rebind’ in ‘class my_allocator<char>’
       typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type;
                                                               ^~~~~~~~~~~~~~~~~

哪个指出basic_string.h第2616行正在编译 - 但是如果在basic_string.h的第一行之一检查_GLIBCXX_USE_CXX11_ABI并且在构建中不包含第2616行时,如果使用标志-D_GLIBCXX_USE_CXX11_ABI = 1进行编译,那该怎么办呢?阶段如果是真的吗?

我使用shell脚本构建:

g++-6 -std=c++11 -Wall -D_GLIBCXX_USE_CXX11_ABI=1 broken.cpp -o broken

我使用的Ubuntu版本是:

Distributor ID: Ubuntu
Description:    Ubuntu 14.04.5 LTS
Release:    14.04
Codename:   trusty

[编辑:此行以下的所有内容]

g ++ - 6 -v给出:

Using built-in specs.
COLLECT_GCC=g++-6
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 6.3.0-18ubuntu2~14.04' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-6 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=gcc4-compatible --disable-libstdcxx-dual-abi --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 6.3.0 20170519 (Ubuntu/Linaro 6.3.0-18ubuntu2~14.04) 

这是一个全新安装的Ubuntu,只使用sudo add-apt-repository ppa安装了cmake,g ++ 6和git:ubuntu-toolchain -r / test和apt-get。我在Travis CI上遇到了同样的问题,这就是为什么要尝试在新的Ubuntu安装上进行本地化。

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

分配器必须实现几件事才能在STL的所有上下文中使用:

你已经拥有的东西:

  • value_type指定分配的对象类型
  • allocatedeallocate
  • ==!=检查通过一个分配器分配的存储是否可以通过另一个分配器解除分配。
  • 拷贝构造

隐式生成的内容:

  • copy-assignment operator
  • 移动构造函数,移动赋值运算符

缺少什么:

  • 重新绑定构造函数:类似于

    template<typename OTHER_TYPE>
    my_allocator(const my_allocator<OTHER_TYPE> &other) ...
    

    允许STL使用自定义节点类型来存储元素,而您只为元素类型提供了一个分配器,例如:在set或类似的数据结构中

rebind结构本身是可选的,如果提供了重新绑定构造函数,并且您的模板参数足够简单&#39; (请参阅Allocator conceptstd::allocator_traits