我正在分析一个或多个从二进制文件加载的大型数据表中的列。每列都可以是几种预定义类型中的一种,本质上是一个
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
?
只要变体中的第一个条目具有默认构造函数,这就有效。
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 开始