簡體   English   中英

在C ++中使用不同的分配器復制對象

[英]Copying objects using different allocators in C++

所以我有一個很好的持久化分配器類persistent_alloc<T> ,它允許我在持久內存中分配C ++容器對象和字符串,該內存由一個mmaped文件支持,該文件可以從我的程序的一次運行到下一次運行。

當我想做任何混合持久和非持久對象的事情時,我的問題就來了。 例如,我有

typedef std::basic_string<char, std::char_traits<char>, persistent_alloc<char>> pstring;

pstring a, b, c;
std::string x, y, z;

我希望能夠做到這樣的事情:

if (a == x)
    a = y;
c = z + b;

依此類推,但默認情況下它不起作用,因為pstringstd::string是不相關的類型。 就比較而言,我可以定義:

template<typename Alloc1, typename Alloc2> inline bool
operator==(const std::basic_string<char, std::char_traits<char>, Alloc1> &a,
           const std::basic_string<char, std::char_traits<char>, Alloc2> &b)
{
    return strcmp(a.c_str(), b.c_str()) == 0;
}

...現在我可以比較字符串的相等性。 但是為每個操作添加這些操作似乎很痛苦 - 似乎它們應該由標准庫提供。 更糟糕的是,賦值運算符和復制構造函數必須是成員,不能像這樣定義為全局內聯函數。

這樣做有合理的方法嗎? 或者我是否必須有效地重寫整個標准庫以有效地支持分配器?

有一種方法可以解決這個問題,但你需要在盒子外思考一下。 你需要的是一個可以從std::string和你的allocator字符串隱式構造的中間類型。

目前在C ++委員會面前這樣建議 它基於Google已經存在的Apache許可實施 它叫做basic_string_ref ; 它是一個模板類,它基本上是指向字符串中第一個字符的指針和一個表示字符串長度的大小。 從某種意義上講,它不是一個真正的容器,它不管理內存。

這正是你需要的。

basic_string_ref特定字符類型和特性類型是由隱式施工的std::basic_string 不管分配器。

所有比較運算符都可以用basic_string_ref定義。 由於它可以從std::basic_string隱式構造(並且幾乎可以自由構造),因此它可以透明地用於不同分配的字符串之間的比較。

做任務相當棘手,但可行。 它需要一系列轉換:

a = pstring{basic_string_ref{y}};

當然不是最漂亮的代碼。 我們更願意簡單地將std::basic_string的復制構造函數和賦值運算符更改為分配器不可知。 但由於這不可行,這真的是下一個最好的事情。 你甚至可以將它包裝在模板函數中:

template<typename DestAllocator, typename SourceAllocator, typename charT, typename traits>
std::basic_string<charT, traits, DestAllocator> conv_str(const std::basic_string<charT, traits, SourceAllocator> &input)
{
  return std::basic_string<charT, traits, DestAllocator>{basic_string_ref<charT, traits>{y}};
}

當然,如果你能做到這一點,你可以這樣做:

template<typename DestAllocator, typename SourceAllocator, typename charT, typename traits>
std::basic_string<charT, traits, DestAllocator> conv_str(const std::basic_string<charT, traits, SourceAllocator> &input)
{
  return std::basic_string<charT, traits, DestAllocator>{y.begin(), y.end()};
}

如果這只是std::basic_string一部分會很好,所以你不需要解決方法。 但事實並非如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM