Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C+中使用不同的分配器复制对象+; p>所以我有一个很好的持久分配器类持久性OLC/C >代码>,它允许我在持久内存中分配C++容器对象和字符串,它由MAMAPED文件支持,可以从一个程序运行到下一个程序。_C++_C++11 - Fatal编程技术网

在C+中使用不同的分配器复制对象+; p>所以我有一个很好的持久分配器类持久性OLC/C >代码>,它允许我在持久内存中分配C++容器对象和字符串,它由MAMAPED文件支持,可以从一个程序运行到下一个程序。

在C+中使用不同的分配器复制对象+; p>所以我有一个很好的持久分配器类持久性OLC/C >代码>,它允许我在持久内存中分配C++容器对象和字符串,它由MAMAPED文件支持,可以从一个程序运行到下一个程序。,c++,c++11,C++,C++11,当我想做任何混合持久性和非持久性对象的事情时,我的问题就来了。例如,我有 typedef std::basic_string<char, std::char_traits<char>, persistent_alloc<char>> pstring; pstring a, b, c; std::string x, y, z; 以此类推,但默认情况下它不起作用,因为pstring和std::string是不相关的类型。现在,就比较而言,我可以定义: temp

当我想做任何混合持久性和非持久性对象的事情时,我的问题就来了。例如,我有

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

pstring a, b, c;
std::string x, y, z;
以此类推,但默认情况下它不起作用,因为
pstring
std::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;
}
模板内联bool
运算符==(常量标准::基本字符串&a,
const std::basic_字符串(&b)
{
返回strcmp(a.c_str(),b.c_str())==0;
}
…现在我可以比较字符串是否相等。但是为每个操作添加这些似乎是一件痛苦的事情——似乎它们应该由标准库提供。更糟糕的是,赋值运算符和复制构造函数必须是成员,不能像这样定义为全局内联函数


有没有一种合理的方法可以做到这一点?或者我必须有效地重写整个标准库以有效地支持分配器吗?

有一种方法可以解决这个问题,但您需要跳出框框思考一下。您需要的是一个中间类型,它可以从
std::string
和分配器字符串隐式构造

有一个问题。它是基于。它被称为
basic_string_ref
;它是一个模板类,基本上是一个指向字符串中第一个字符的指针和一个表示字符串长度的大小。它不是一个真正的容器,因为它不管理内存

这正是你需要的

特定字符类型和特征类型的
basic\u string\u ref
可以从
std::basic\u string
隐式构造,而不考虑分配器

所有比较运算符都可以根据
basic\u string\u 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}};
}
模板
std::basic_string conv_str(const std::basic_string&input)
{
返回std::basic_string{basic_string_ref{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 conv_str(const std::basic_string&input)
{
返回std::basic_字符串{y.begin(),y.end()};
}

如果这只是
std::basic_string
的一部分,那就太好了,这样您就不需要解决问题了。但事实并非如此。

这在过去已经提交给标准委员会。当前分配器模型和其他模型的限制如所示。C++中的分配器模型不是很好定义,它实际上是有问题的(N1850中的替代方案在不同的基础上也是有问题的):请注意,除非类型满足 STD::ISS- TrviaLyCopabel::value=Trime< /Cord>:除非将永久内存还原到完全相同的绝对位置或类似位置。您希望某些操作的行为相同,而某些操作的行为不同。如果你不把它拼出来,编译器怎么知道呢?@BoPersson:不难弄清楚哪些应该不同,哪些不应该不同。也就是说,实际需要分配器工作的那些应该是不同的。你知道,可以分配内存的那些。@KerrekSB:如果你想让指针正常工作,持久内存就需要在同一个虚拟地址上恢复。这使问题变得简单一些,但不能完全解决。如果不改变标准库,我仍然看不到任何让赋值运算符工作的方法。@chrisdd:是的,我知道;我是这么说的。你可以得到你想要的80%并处理一些次要的API问题,或者你可以重写
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>{y.begin(), y.end()};
}