下面是一段简单的代码。
#include <algorithm>
#include <iostream>
#include <iterator>
#include <unordered_map>
#include <vector>
using namespace std;
static void print(const vector<int>& v) {
copy(
begin(v),
end(v),
ostream_iterator<int>{cout, ", "}
);
cout << endl;
}
int main() {
vector<pair<int, string>> v {1, 2, 3, 4, 5};
cout << endl << "In vector:" << endl;
print(v);
return 0;
}
我试着使用模板编程来打印,因为我想通用化 container
是任何类型(vector
, map
, list
等),元素也可以是任何类型的元素(int
, double
等)。)
template <typename C, typename T>
static void print(const C& container) {
copy(
begin(container),
end(container),
ostream_iterator<T>{cout, ", "}
);
cout << endl;
}
但是,它不会编译。
In function 'int main()':
prog.cc:31:12: error: no matching function for call to 'print(std::vector<int>&)'
31 | print(v);
| ^
prog.cc:18:13: note: candidate: 'template<class C, class T> void print(const C&)'
18 | static void print(const C& container) {
| ^~~~~
prog.cc:18:13: note: template argument deduction/substitution failed:
prog.cc:31:12: note: couldn't deduce template parameter 'T'
31 | print(v);
| ^
我猜测是类型名 T
不是通过函数明确输入 print()
确切地说,它的名字是 ostream_iterator<int>{cout, ", "}
哪个编译器不知道如何推断它的类型(为什么?)。
我想知道如何将两个类型名(C
和 T
)成 print()
函数,尽管只有类型名 C
是输入?
你需要指定类型 T
明确地调用 print
(例如 print(v, int)
,或者你写 print
以使其导出容器本身的值类型。通常的方法是使用 typename C::value_type
,它存在于所有标准容器中。
template <typename C>
void print(const C& container) {
using T = typename C::value_type;
copy(
begin(container),
end(container),
ostream_iterator<T>{cout, ", "}
);
cout << endl;
}
如果你不喜欢这种方式,或者你的容器可能并不总是有一个... ... value_type
成员,那么你可以很容易地直接导出值类型。
template <typename C>
void print(const C& container) {
using T = std::remove_const_t<decltype(*std::cbegin(container))>;
copy(
std::cbegin(container),
std::cend(container),
ostream_iterator<T>{cout, ", "}
);
cout << endl;
}
你不需要指定第二个模板参数。大多数STL容器都有一个成员 value_type
就是为了这个目的。所以你的功能需要是。
template <typename C, typename T = typename C::value_type>
static void print(const C& container) {
copy(
begin(container),
end(container),
ostream_iterator<T>{cout, ", "}
);
cout << endl;
}