如何使用C ++为向量的向量编写通用打印

lor*_*ire 0 c++ templates vector

我在.cpp中的初始实现方法如下所示:

using namespace std;
...
template <typename T>
void print2dvector(vector<vector<T> > v) {
    for(int i = 0; i < v.size(); i++) {
        for(int j = 0; j < v[i].size(); j++) {
            cout << v[i][j] << " ";
        }
        cout << endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

.h文件中的声明如下

template <typename T> void print2dvector(std::vector<std::vector<T> > v);
Run Code Online (Sandbox Code Playgroud)

这是我的用法

print2dvector<int>(vec_of_vec);
Run Code Online (Sandbox Code Playgroud)

编译阶段已通过,但在链接阶段失败。错误如下:

Undefined symbols for architecture x86_64:
  "void print2dvector<int>(std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >)", referenced from:
   spiral_matrix_ii_Challenge::Execute() in spiral_matrix_ii.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)

如果让我在概念上错过实现此功能的任何方法,请告诉我。

Vic*_*voy 5

链接错误意味着您的模板没有实例化,并且链接器无法链接这些符号。正如@Piotr Skonticki所说,解决此问题的最佳选择是在使用位置或头文件中实现它。请参阅以获取更多信息。

关于代码-我会这样写:

#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>

template<typename T>
void printVector(const T& t) {
    std::copy(t.cbegin(), t.cend(), std::ostream_iterator<typename T::value_type>(std::cout, ", "));
}

template<typename T>
void printVectorInVector(const T& t) {
    std::for_each(t.cbegin(), t.cend(), printVector<typename T::value_type>);
}

int main() {
    std::vector<int> a = {1, 3, 5, 7, 9};
    std::vector<std::vector<int>> b;
    b.push_back(a);
    b.push_back(a);
    printVectorInVector(b);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我认为这比您的解决方案更好,因为:

  1. 它不依赖于可迭代的集合类型(它可以是向量,列表或具有迭代器和类似于stl的迭代器接口的任何对象)。
  2. 它不依赖于值类型-它总是从可迭代集合(T::value_type)中获取正确的值类型。
  3. 它还避免了对象复制,因为它是通过const引用获取的。