std::string 使用自定义分配器
std::string with a custom allocator
所以我目前正在编写内存调试器,为此我需要 stl 容器对象来使用未跟踪的分配器。
我的整个代码库中都有 std::string,所以我对它进行了 typedef 以使用我未跟踪的分配器:
typedef std::basic_string<char, std::char_traits<char>, UntrackedAllocator<char>> String;
现在,当我尝试这样做时:
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); }
这是我的未跟踪分配器的样子:
#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 ,这非常烦人。
问题是将复制 c'tors 声明为 explicit
。
将 UntrackedAllocator
副本更改为:
inline UntrackedAllocator(UntrackedAllocator const&) {}
解决了编译问题,一切正常:
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
的赋值运算符需要分配器的隐式复制构造。
所以我目前正在编写内存调试器,为此我需要 stl 容器对象来使用未跟踪的分配器。
我的整个代码库中都有 std::string,所以我对它进行了 typedef 以使用我未跟踪的分配器:
typedef std::basic_string<char, std::char_traits<char>, UntrackedAllocator<char>> String;
现在,当我尝试这样做时:
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); }
这是我的未跟踪分配器的样子:
#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 ,这非常烦人。
问题是将复制 c'tors 声明为 explicit
。
将 UntrackedAllocator
副本更改为:
inline UntrackedAllocator(UntrackedAllocator const&) {}
解决了编译问题,一切正常:
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
的赋值运算符需要分配器的隐式复制构造。