如何在 C++ 中将指针或 unique_ptr 初始化为变体

问题描述 投票:0回答:1

我正在分析一个或多个从二进制文件加载的大型数据表中的列。每列都可以是几种预定义类型中的一种,本质上是一个

vector
。我将列定义为几个向量的
variant
。在下面的玩具示例中,我只使用了两种可能的类型(在我的项目中,有 6 或 7 种类型)。基本上,我需要一个从给定文件加载单个列的函数。为了避免调用向量的复制构造函数,我想将每个加载的列保留在堆内存中,也就是说,将其作为
unique_ptr
.

我尝试实现这样的功能,但 C++ 编译器无法将加载的矢量指针分配给我的

variant
指针变量。我在下面给出了一个示例代码片段:

#include <cstdint>
#include <iostream>
#include <memory>
#include <string>
#include <variant>
#include <vector>

using column_t = std::variant<
    std::vector<std::uint32_t>,
    std::vector<double>>;

std::unique_ptr<column_t> load(const std::string& file_name) {
    column_t* result;
    // The column type is encoded in the file contents, but
    // in this toy example, we are not reading from the file
    switch (file_name.size() % 2) {
        case 0:
            result = new std::vector<std::uint32_t>();
            (std::get<std::vector<std::uint32_t>>(*result)).push_back(5);
            break;
        default: // 1
            result = new std::vector<double>();
            (std::get<std::vector<double>>(*result)).push_back(3.14);
    }
    return std::unique_ptr<column_t>(result);
}

inline std::size_t get_length(const column_t& v) {
    switch (v.index()) {
        case 0:
            return std::get<0>(v).size();
        default: // 1
            return std::get<1>(v).size();
    }
}

int main()
{
    std::unique_ptr<column_t> values = load("myfile");
    std::cout << "Loaded a vector of length "
              << get_length(*values.get()) << std::endl;
    return 0;
}

我知道我可以重写函数以简单地返回一个

column_t
对象,但是,在下游分析任务中使用智能指针会更直观。谁能指出我需要使用的正确结构,以便将指针(或直接
unique_ptr
实例)分配给变量
result

c++ unique-ptr variant
1个回答
0
投票

只要变体中的第一个条目具有默认构造函数,这就有效。

std::unique_ptr<column_t> load(const std::string& file_name) {
    std::unique_ptr<column_t> result = std::make_unique<column_t>();
    switch (file_name.size() % 2) {
        case 0:
            result->emplace<std::vector<std::uint32_t>>();
            (std::get<std::vector<std::uint32_t>>(*result)).push_back(5);
            break;
        default: // 1
            result->emplace<std::vector<double>>();
            (std::get<std::vector<double>>(*result)).push_back(3.14);
    }
    return result;
}

或者你可以写

std::unique_ptr<column_t> result;
...
result = std::make_unique<column_t(
      std::in_place_type_t<std::vector<std::uint32_t>>{});

从 C++17 开始

© www.soinside.com 2019 - 2024. All rights reserved.