您的包含是什么样的?该错误消息似乎表明您没有包含正确的文件。 arrow:Int64Builder 的完整定义在 arrow/array/builder_primitive.h 中,但您通常可以只包含 arrow/api.h 以获取所有内容。
以下为我编译:
#include <iostream>
#include <arrow/api.h>
arrow::Status Main() {
std::size_t rowCount = 5;
arrow::MemoryPool* pool = arrow::default_memory_pool();
std::vector<arrow::Int64Builder> builders;
for (std::size_t i = 0; i < 2; i++) {
arrow::Int64Builder tmp(pool);
ARROW_RETURN_NOT_OK(tmp.Reserve(rowCount));
builders.push_back(std::move(tmp));
}
return arrow::Status::OK();
}
int main() {
auto status = Main();
if (!status.ok()) {
std::cerr << "Err: " << status << std::endl;
return 1;
}
return 0;
}
您的示例的一个小变化是构建器没有复制构造函数/无法复制。所以我不得不std::move把它放到向量中。
此外,如果您想要一个包含许多不同类型构建器的单一集合,那么您可能需要std::vector<std::unique_ptr<arrow::ArrayBuilder>>,并且您需要在堆上构建您的构建器。
您可能会遇到的一个挑战是构建器对于Append 方法都有不同的签名(例如,Int64Builder 有Append(long),但StringBuilder 有Append(arrow::util::string_view))。因此,arrow::ArrayBuilder 并没有真正的 Append 方法(如果您碰巧已经将数据作为 Arrow C++ 标量,则有一些方法采用标量)。但是,当您需要追加时,您可以通过转换为适当的类型来克服这个问题。
更新:
如果您真的想避免强制转换并且您提前知道架构,您可以按照以下方式做一些事情......
std::vector<std::function<arrow::Status(const Row&)>> append_funcs;
std::vector<std::shared_ptr<arrow::ArrayBuilder>> builders;
for (std::size_t i = 0; i < schema.fields().size(); i++) {
const auto& field = schema.fields()[i];
if (isInt32(field)) {
auto int_builder = std::make_shared<Int32Builder>();
append_funcs.push_back([int_builder] (const Row& row) ({
int val = row.GetCell<int>(i);
return int_builder->Append(val);
});
builders.push_back(std::move(int_builder));
} else if {
// Other types go here
}
}
// Later
for (const auto& row : rows) {
for (const auto& append_func : append_funcs) {
ARROW_RETURN_NOT_OK(append_func(row));
}
}
注意:我编造了Row,因为我不知道您的数据最初是什么格式。我还编造了isInt32,因为我不记得如何检查我的头顶。
这使用shared_ptr 而不是unique_ptr,因为您需要两份副本,一份在lambda 的捕获中,另一份在builders 数组中。