【问题标题】:Custom allocators with clang++ v4 and gcc 6.3 libraries使用 clang++ v4 和 gcc 6.3 库的自定义分配器
【发布时间】:2017-05-11 19:38:24
【问题描述】:

在库附带 gcc 6.3.1 的系统 (arch linux) 上使用带有 clang++ 4.0.0 的自定义分配器时遇到了很多麻烦。这是一个最小的非工作示例:

#include <string>

struct myalloc : std::allocator<char> {
  using std::allocator<char>::allocator;
};

struct mystring 
  : std::basic_string<char, std::char_traits<char>, myalloc> {
  using std::basic_string<char, std::char_traits<char>, myalloc>::basic_string;
};

int
main()
{
  mystring r = "hello";
  mystring s (std::move(r));
}

我的意图显然是让myalloc 成为一个自定义分配器,其行为与系统std::allocator 完全相同,mystringstd::string 相同,只是它使用myalloc。这应该是最不可能引起问题的情况。 (显然,一旦这工作正常,我想进一步自定义分配器。)

代码用g++ -std=c++14 -Wall -Werror 编译干净,但clang++ -std=c++14 失败:

In file included from strerror.cc:1:
In file included from /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/string:52:
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/basic_string.h:477:9: error: 
      no matching constructor for initialization of
      'std::__cxx11::basic_string<char, std::char_traits<char>,
      myalloc>::_Alloc_hider'
      : _M_dataplus(_M_local_data(), std::move(__str._M_get_allocator()))
        ^           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
strerror.cc:7:8: note: in instantiation of member function
      'std::__cxx11::basic_string<char, std::char_traits<char>,
      myalloc>::basic_string' requested here
struct mystring 
       ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/basic_string.h:109:2: note: 
      candidate constructor not viable: no known conversion from 'typename
      std::remove_reference<allocator<char> &>::type' (aka
      'std::allocator<char>') to 'const myalloc' for 2nd argument
        _Alloc_hider(pointer __dat, const _Alloc& __a = _Alloc())
        ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/basic_string.h:107:14: note: 
      candidate constructor (the implicit move constructor) not viable: requires
      1 argument, but 2 were provided
      struct _Alloc_hider : allocator_type // TODO check __is_final
             ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/basic_string.h:107:14: note: 
      candidate constructor (the implicit copy constructor) not viable: requires
      1 argument, but 2 were provided
1 error generated.

这只是 clang 或 gcc 库中的错误,还是我的代码在概念上存在问题?

【问题讨论】:

  • 你为什么派生自basic_string?你的自定义字符串不应该只是using mystring = std::basic_string&lt;char, std::char_traits&lt;char&gt;, myalloc&gt;吗?
  • 我需要在我的真实字符串类中添加几个构造函数,并为示例进行了简化。
  • 标准中没有任何内容坚持 basic_string 必须是可继承的...
  • @RichardHodges 除非另有说明,否则所有类都不应该是可继承的吗?可继承这个词似乎甚至没有出现在 C++14 标准中。因此,除非您有一个私有虚拟超类,其中只有非公共构造函数或标准中其他访问控制概念涵盖的某些其他边缘条件,否则标准在哪里甚至支持不可继承类的概念?

标签: c++ clang c++14


【解决方案1】:

您的最小示例的最小修复是将此成员添加到struct myalloc

template<class> struct rebind {
    using other = myalloc;
};

当然最好不要从 std::allocator 继承(在这种情况下你不需要重新绑定),也不要从 string 继承,这些类不打算作为公共基础。

【讨论】:

    猜你喜欢
    • 2016-11-04
    • 1970-01-01
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 2017-06-22
    • 2014-08-12
    • 1970-01-01
    • 2020-01-17
    相关资源
    最近更新 更多