对于下面显示的简单代码:
#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()
函数,尽管仅输入typename 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;
}
关于c++ - C++模板:如何在仅输入1个函数的情况下使用2个类型名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61488219/