c++ 相同索引元素的元组的向量;确定向量是否大小相同

sgtfey8w  于 2023-04-01  发布在  其他
关注(0)|答案(1)|浏览(167)

我希望创建一个vector,它存储来自不同vector的相同索引元素的元组。虽然我能够实现它,但如果调用者传入不同大小的vector,我想知道是否有一种方法可以确定所有传入的vector是否具有相同的大小。

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} }
bfnvny8b

bfnvny8b1#

显示的代码无论如何都不能像预期的那样工作。sizeof...提供了包中参数的数量,而不是包中单个元素的大小。
可能是这样的(假设C++17或更高版本):

template <typename Arg1, typename... Args>
std::vector<std::tuple<Arg1, Args...>> Foo(const std::vector<Arg1>& 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<Arg1, Args...>> result;

    for (size_t i = 0; i < vec1.size(); ++i) 
    {
        // emplace_back is pointless if you use don't pass
        // the constructor arguments directly
        // Also make_tuple doesn't always produce tuple<Args...>.
        result.emplace_back(vec1[i], vecs[i]...);
    }

    return result;
}

但我会考虑是否真的需要将这个函数限制为std::vector。在C++20中,您可以接受任何范围并从std::range_value_t确定元组类型,或者接受迭代器对并通过解引用迭代器来确定元组类型。
你也可以考虑是否让函数完美转发没有意义。
如果你想允许一个空的参数列表,那么结果向量应该有多大就不明确了。在这种情况下,我建议添加一个特定的重载来处理它。

相关问题