【发布时间】:2013-01-30 04:20:51
【问题描述】:
将unique_ptr<char[]> 移动到unique_ptr<const char[]> 的最佳习语是什么?
用例:假设您在某个缓冲区中创建了一个 C 字符串。为了确保在发生异常时进行适当的清理,可以使用unique_ptr 引用该缓冲区。构造字符串后,您可能希望将其移动到某个类成员,该成员声明为 unique_ptr<const char[]>,以避免进一步修改字符串。
这是我迄今为止最好的:
std::unique_ptr<const char[]> res;
std::unique_ptr<char[]> buf(new char[4]);
buf[0] = 'f';
buf[1] = buf[2] = 'o';
buf[3] = '\0';
res = std::unique_ptr<const char[]>(const_cast<const char*>(buf.release()));
简单地移动似乎不起作用,可能是由于删除器类型不同。即使省略从char 到const char 的显式转换也不起作用,如Should `unique_ptr< T const [] >` accept a `T*` constructor argument? 中所述
有没有更好的成语来实现我上面概述的内容?我的代码看起来很笨拙,而且考虑到这个概念一开始听起来多么简单,我的代码相当冗长。
【问题讨论】:
-
使用
res = std::move(buf);在 VS2010 和 VS2012 以及 Clang 主干(使用 libc++ 主干)中对我来说编译得很好。不过,GCC 4.7.2 对此感到窒息。 -
看来 GCC 4.8 主干解决了这个问题,你也可以在那里使用
res = std::move(buf)。否则,我认为你无法绕过这个演员阵容。不过,您可以将该行缩短为res.reset(const_cast<char const*>(buf.release()));。 -
@Xeo,关于 GCC 4.8 的信息和使用
reset的较短成语都非常有价值。请将它们作为答案发布。 -
我知道一种更好的方法:使用
std::string。只是不要复制它,它会很好地移动。 -
@NicolBolas:我正在组装
std::exception::what()的覆盖的返回值,它必须是const char*。我在std::string上完成了大部分工作,所以buf是我分配给的字符数组,res是我用来保持结果有效的成员,直到异常本身被收集。我想我可以改为返回std::string::c_str()的结果,我猜。但是不能强制让类不操纵该字符串,因为没有可以分配但不能就地修改的std::string。这使得我在这里的整个问题不适用。
标签: c++ c++11 constants unique-ptr