如何打印任意数量或随机访问的容器?

How to print any number or random access containers?

假设我有 N 个不同类型的随机访问容器(例如 std::vectorstd::array),并且所有容器的长度都相同。我想写一个以列顺序打印它们的函数,即:

#include <vector>
#include <iostream>
#include <array>
#include <complex>

constexpr int nr=100;

void print(const std::vector<double>& d1, const std::array<std::complex<double>,nr>& b1, const std::vector<int>& b2, const std::array<double,nr>& d2)
{
    for(int i=0; i<nr; ++i)
    std::cout<<b1[i]<<" "<<d1[i]<<" "<<b2[i]<<" "<<d2[i]<<"\n";
}

现在假设所有容器都包含标准数字类型,我可以编写一个可变参数模板函数,如下所示:

template<typename... T>
void vprint(T... cs)
{
    constexpr int nc=sizeof...(T);
    std::vector<std::vector<std::complex<long double>>> v(nr, std::vector<std::complex<long double>>(nc));
    //then fill v recursively with all the cs and print it
}

我使用 std::complex<long double> 的地方,因为它会包含任何可能的数字。 然而,这个解决方案并不令人满意,因为我分配了额外的内存,我正在转换一些整数,破坏了输出(可能还有精度),最后,如果任何容器包含不能平凡转换为的可打印类型,该解决方案就不起作用一个数字类型。 关于如何编写更通用的解决方案有什么想法吗?

您不需要创建任何临时文件。这是一个要求至少存在一个容器的实现,但您可以通过添加空重载来删除该要求:

// Handles empty parameters by doing nothing
void vprint() {}

// Handle non-empty parameters
template<typename T, typename... Ts>
void vprint(const T& front, const Ts&... cs) {
    for (int i = 0; i < front.size(); ++i) {
        std::cout << front[i];
        ((std::cout << ' ' << cs[i]), ...);
        std::cout << '\n';
    }
}

这利用 C++17 fold expressions 在手动打印第一个元素后打印每个容器的第 i 个元素。显式处理第一个还可以确保我们不会在没有分支的每一行的末尾(或开头)打印​​额外的 space。

如果您无法访问 C++17,它仍然可以实现,但会比这丑陋得多。

根据 Louis 的评论,您还可以在 for 循环之前添加一个 assert 以确保所有容器中至少包含 front.size() 个元素以确保安全:

assert(((cs.size() >= front.size()) && ...));

>= 更改为 == 以实现严格相等。

用法:

int main() {
    std::array<int, 4> a{1,2,3,4};
    std::vector<int> b{5,6,7,8};
    vprint(a, b);
}

版画

1 5
2 6
3 7
4 8

https://godbolt.org/z/z6s34TaT9