为什么编译器不能推导模板模板参数?
Why compiler cannot deduce template template argument?
我想编写一个函数,它接受一个具有任何类型的通用容器并打印它。
暂且不谈它对某些关联容器不起作用,重点关注问题:
template<template<typename> typename Cont, typename T>
void print(const Cont<T>& cont)
{
for (const auto it : cont)
{
cout << it << " ";
}
cout << endl;
}
int main()
{
vector<string> v;
print(v);
}
错误状态:
error C2672: 'print': no matching overloaded function found
error C3207: 'print': invalid template argument for 'Cont', class template expected
谁能解释一下为什么编译器不能在这里推导出类型?
即使我明确指出 print<vector<string>>(v)
?
std::vector
不止一个 class-template-args.
template<
class T, // -----------> you have mentioned!
class Allocator = std::allocator<T> // -----> this didn't!
> class vector;
但是你只提供了一个。这就是没有匹配的重载编译器错误的原因。
为了解决这个问题,您需要在模板 template arg 中提供可变参数。
template<template<typename...> typename Cont, typename T>
// ^^^^^^^^^^^^^^^^^^^^
void print(const Cont<T>& cont)
{
for (const auto& it : cont) {
std::cout << it << " ";
}
std::cout << std::endl;
}
但是,您可以简单地做到这一点
template <typename Cont>
void print(const Cont& cont)
{
// ...
}
或者像标准方式一样,传递 the begin and end iterator of the container to the function
#include <algorithm> // std::copy
#include <iterator> // std::iterator_traits
template<typename Iterator>
constexpr void print(const Iterator begin, const Iterator end) noexcept
{
using ValueType = typename std::iterator_traits<Iterator>::value_type;
std::copy(begin, end, std::ostream_iterator<ValueType>(std::cout, " "));
std::cout << "\n";
}
并称其为
print(v.begin(), v.end());
std::vector
定义为
template<
class T,
class Allocator = std::allocator<T>
> class vector;
std::vector
是具有两个模板参数的 class 模板。它不匹配
函数的模板模板参数。
改为
template <typename Cont>
void print(const Cont& cont)
{
for (const auto& elem : cont) {
std::cout << elem << " ";
}
std::cout << std::endl;
}
如果有必要,您可以从容器中推断出 T
。
我想编写一个函数,它接受一个具有任何类型的通用容器并打印它。
暂且不谈它对某些关联容器不起作用,重点关注问题:
template<template<typename> typename Cont, typename T>
void print(const Cont<T>& cont)
{
for (const auto it : cont)
{
cout << it << " ";
}
cout << endl;
}
int main()
{
vector<string> v;
print(v);
}
错误状态:
error C2672: 'print': no matching overloaded function found
error C3207: 'print': invalid template argument for 'Cont', class template expected
谁能解释一下为什么编译器不能在这里推导出类型?
即使我明确指出 print<vector<string>>(v)
?
std::vector
不止一个 class-template-args.
template<
class T, // -----------> you have mentioned!
class Allocator = std::allocator<T> // -----> this didn't!
> class vector;
但是你只提供了一个。这就是没有匹配的重载编译器错误的原因。
为了解决这个问题,您需要在模板 template arg 中提供可变参数。
template<template<typename...> typename Cont, typename T>
// ^^^^^^^^^^^^^^^^^^^^
void print(const Cont<T>& cont)
{
for (const auto& it : cont) {
std::cout << it << " ";
}
std::cout << std::endl;
}
但是,您可以简单地做到这一点
template <typename Cont>
void print(const Cont& cont)
{
// ...
}
或者像标准方式一样,传递 the begin and end iterator of the container to the function
#include <algorithm> // std::copy
#include <iterator> // std::iterator_traits
template<typename Iterator>
constexpr void print(const Iterator begin, const Iterator end) noexcept
{
using ValueType = typename std::iterator_traits<Iterator>::value_type;
std::copy(begin, end, std::ostream_iterator<ValueType>(std::cout, " "));
std::cout << "\n";
}
并称其为
print(v.begin(), v.end());
std::vector
定义为
template<
class T,
class Allocator = std::allocator<T>
> class vector;
std::vector
是具有两个模板参数的 class 模板。它不匹配
函数的模板模板参数。
改为
template <typename Cont>
void print(const Cont& cont)
{
for (const auto& elem : cont) {
std::cout << elem << " ";
}
std::cout << std::endl;
}
如果有必要,您可以从容器中推断出 T
。