我正在寻找一个向量来存储来自不同向量的相同索引元素的元组。 虽然我能够实现它,但如果调用者传入不同大小的向量,我想知道是否有一种方法可以确定是否所有传入的向量都具有相同的大小。
template <typename... Args>
std::vector<std::tuple<Args...>> Foo(const std::vector<Args>&... vecs)
{
std::vector<std::tuple<Args...>> result;
const auto elems = sizeof...(vecs);
std::cout << "Elems = " << elems << std::endl;
for (size_t i = 0; i < elems; ++i)
{
result.emplace_back(std::make_tuple(vecs[i]...));
}
return result;
}
vector<int> v1 = {1, 4, 8};
vector<double> v2 = {1.1, 4.1, 8.1};
auto vec1 = Foo(v1, v2); // { {1, 1.1}, {4, 4.1}, {8, 8.1} }
显示的代码无论如何都不能按预期工作。
sizeof...
为您提供包中参数的数量,而不是包中各个元素的大小。
也许是这样的(假设 C++17 或更高版本):
template <typename... Args>
std::vector<std::tuple<Args...>> Foo(const std::vector<Args>& vec1, const std::vector<Args>&... vecs)
{
if(((vec1.size() != vecs.size()) || ...))
throw std::invalid_argument("All arguments to Foo must have equal length.");
std::vector<std::tuple<Args...>> result;
for (size_t i = 0; i < vec1.size(); ++i)
{
result.emplace_back(std::make_tuple(vecs[i]...));
}
return result;
}
但我会考虑你是否真的需要将这个功能具体限制为
std::vector
。您可以接受任何范围并从 C++20 中的std::range_value_t
确定元组类型,或者接受迭代器对并通过取消引用迭代器来确定元组类型。
你也可以考虑把函数做成完美转发是不是没有意义
如果你想允许一个空的参数列表,那么结果向量应该有多大是不明确的。在那种情况下,我建议添加一个特定的重载处理它。