有没有比这更简洁的方法来初始化 unique_ptr<char[]> ?

Is there a more concise way to initialize a unique_ptr<char[]> than this?

所以目前我有:

std::string a;
std::unique_ptr<char[]> b(std::make_unique<char[]>(a.size() + 1));
std::copy(std::begin(a), std::end(a), b.get());

是否可以一步直接初始化?

Is it is possible to initialize this directly in one step?

我建议将其保留为 std::stringstd::vector<char>

不过,如果你真的坚持,!使用 ,这可以完成。

std::unique_ptr<char[]> b = [&a]() {
   auto temp(std::make_unique<char[]>(a.size() + 1));
   std::copy(std::begin(a), std::end(a), temp.get());
   return temp;
}(); // invoke the lambda here!

temp 将移动构建到 b

(See a Demo)


如果稍后不再使用字符串 a,您可以使用 std::make_move_iterator.

将其移动到 std::unique_ptr<char[]>
#include <iterator>  // std::make_move_iterator

std::unique_ptr<char[]> b(std::make_unique<char[]>(a.size() + 1));
std::copy(std::make_move_iterator(std::begin(a)),
   std::make_move_iterator(std::end(a)), b.get());

如果需要一步完成,请像上面那样将其打包到 lambda。

这是使用 strdup 和自定义删除器的变体。

请注意使用 char 作为 std::unique_ptr 的第一个模板参数而不是 char[] 因为 strdup 将给出回一个 char*.

自定义删除器用于 free 内存而不是 delete 它,因为 strdup 将使用 malloc 而不是 new 的某种风格来分配内存。

而且您当然不需要在这里为 CustomString 使用 typedef(或 using,如果您愿意的话);只是为了简洁起见。

#include <cstdlib>
#include <cstring>
#include <memory>
#include <string>

int main()
{
    // Some reusable utility code for a custom deleter to call 'free' instead of 'delete'.
    struct CustomDeleter
    {
        void operator()(char* const p) const
        {
            free(p);
        }
    };
    typedef std::unique_ptr<char, CustomDeleter> CustomString;

    const std::string a("whatever");
    // "Concise" one step initialization...
    const CustomString b(_strdup(a.c_str()));

    return 0;
}

不提倡将此作为执行此操作的理想方式,但希望将其作为执行您要求的一步初始化的“方式”分享。