带有自定义分配器的 std::string [英] std::string with a custom allocator

查看:51
本文介绍了带有自定义分配器的 std::string的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我目前正在编写内存调试器,为此我需要 stl 容器对象来使用未跟踪的分配器.

So I'm currently in the process of writing a memory debugger and to do that I need stl container objects to use an untracked allocator.

我在整个代码库中都使用了 std::string,所以我将它定义为使用我未跟踪的分配器:

I have std::string peppered throughout my entire codebase, so I typedef'd it to use my untracked allocator:

typedef std::basic_string<char, std::char_traits<char>, UntrackedAllocator<char>> String;

现在当我尝试这样做时:

Now when I try to do this:

String str { "Some string" };
String copy = str;

我收到此错误:

/usr/local/include/c++/7.1.0/ext/alloc_traits.h:95:67: error: no matching function for call to 'UntrackedAllocator<char>::UntrackedAllocator(UntrackedAllocator<char>)' { return _Base_type::select_on_container_copy_construction(__a); }

这是我的未跟踪分配器的样子:

This is what my Untracked Allocator looks like:

#pragma once

#define NOMINMAX
#undef max

template <typename T>
class UntrackedAllocator {
public:
    typedef T value_type;
    typedef value_type* pointer;
    typedef const value_type* const_pointer;
    typedef value_type& reference;
    typedef const value_type& const_reference;
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;

public:
    template<typename U>
    struct rebind {
        typedef UntrackedAllocator<U> other;
    };

public:
    inline explicit UntrackedAllocator() {}
    inline ~UntrackedAllocator() {}
    inline explicit UntrackedAllocator(UntrackedAllocator const&) {}
    template<typename U>
    inline explicit UntrackedAllocator(UntrackedAllocator<U> const&) {}

    //    address
    inline pointer address(reference r) {
        return &r;
    }

    inline const_pointer address(const_reference r) {
        return &r;
    }

    //    memory allocation
    inline pointer allocate(size_type cnt,
        typename std::allocator<void>::const_pointer = 0) {
        T *ptr = (T*)malloc(cnt * sizeof(T));
        return ptr;
    }

    inline void deallocate(pointer p, size_type cnt) {
        free(p);
    }

    //   size
    inline size_type max_size() const {
        return std::numeric_limits<size_type>::max() / sizeof(T);
    }

    // construction/destruction
    inline void construct(pointer p, const T& t) {
        new(p) T(t);
    }

    inline void destroy(pointer p) {
        p->~T();
    }

    inline bool operator==(UntrackedAllocator const& a) { return this == &a; }
    inline bool operator!=(UntrackedAllocator const& a) { return !operator==(a); }
};

这是我第一次使用自定义分配器,所以我不知道它发生了什么.如果其中一个使用自定义分配器,我无法执行 str1 = str2 ,这令人难以置信.

This is my first time working with custom allocators so I have no idea what's going on with it. It's incredibly annoyning that I can't do str1 = str2 if one of them uses a custom allocator.

推荐答案

问题是复制 c'tors 声明为 explicit.

The problem is the declaration of the copy c'tors as explicit.

更改 UntrackedAllocator 复制 c'tor 到:

Changing the UntrackedAllocator copy c'tor to:

inline UntrackedAllocator(UntrackedAllocator const&) {}

解决了编译问题,一切正常:

Solves the compilation issue and everything works just fine:

int main() {
  String str { "13" };
  String copy = str;
  const char* cstr = str.c_str();
  int out = atoi(cstr);
}

发生这种情况是因为接受 const std::basic_string &std::basic_string 的赋值运算符需要分配器的隐式复制构造.

This happens because the assignment operator of the std::basic_string that accepts const std::basic_string & requires an implicit copy construction of the allocator.

这篇关于带有自定义分配器的 std::string的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆