如何正确调用模板函数
How to call a template function correctly?
我是模板函数的新手,无法处理此错误。希望你能帮忙。
#include <iostream>
#include <vector>
/*
* Print to the screen the content of a vector
* Define function template in the header
*/
template <typename T> void print_vector(T& v) {
for(typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i)
std::cout << *i << ' ';
}
int main() {
std::vector<int> field;
field.resize(12, 1);
/*
for( std::vector<int>::const_iterator i = field.begin(); i != field.end(); ++i)
std::cout << *i << ' ';
*/
print_vector(field);
}
我的代码编译失败,出现了一条很长的错误消息,我甚至无法在这里插入。
error: conversion from ‘std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}’ to non-scalar type ‘std::vector<std::vector<int>, std::allocator<std::vector<int> > >::const_iterator {aka __gnu_cxx::__normal_iterator<const std::vector<int>*, std::vector<std::vector<int>, std::allocator<std::vector<int> > > >}’ requested
utility.h:21:59: error: no match for ‘operator!=’ in ‘i != (& v)->std::vector<_Tp, _Alloc>::end<int, std::allocator<int> >()’
utility.h:21:59: note: candidates are:
In file included from /usr/include/x86_64-linux-gnu/c++/4.7/./bits/c++allocator.h:34:0,
from /usr/include/c++/4.7/bits/allocator.h:48,
from /usr/include/c++/4.7/string:43,
from /usr/include/c++/4.7/bits/locale_classes.h:42,
from /usr/include/c++/4.7/bits/ios_base.h:43,
from /usr/include/c++/4.7/ios:43,
from /usr/include/c++/4.7/istream:40,
from /usr/include/c++/4.7/fstream:40,
from utility.h:4:
/usr/include/c++/4.7/ext/new_allocator.h:134:5: note: template<class _Tp> bool __gnu_cxx::operator!=(const __gnu_cxx::new_allocator<_Tp>&, const __gnu_cxx::new_allocator<_Tp>&)
/usr/include/c++/4.7/ext/new_allocator.h:134:5: note: template argument deduction/substitution failed:
utility.h:21:59: note: ‘std::vector<std::vector<int>, std::allocator<std::vector<int> > >::const_iterator {aka __gnu_cxx::__normal_iterator<const std::vector<int>*, std::vector<std::vector<int>, std::allocator<std::vector<int> > > >}’ is not derived from ‘const __gnu_cxx::new_allocator<_Tp>’
当您调用时
std::vector<int> field;
...
print_vector(field);
print_vector
1中的T
是field
即std::vector<int>
的类型。因此中的typename std::vector<T>::const_iterator
for(typename std::vector<T>::const_iterator i = v.begin();
是v.begin()
(本身是std::vector<int>::iterator
)不可转换到的std::vector<std::vector<int> >::const_iterator
。使用
for(typename T::const_iterator i = v.begin();
相反。
1也就是说:在这种情况下,在由函数模板print_vector
生成的函数中。
在您的函数中:
template <typename T>
void print_vector(T& v) {
for(typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i)
std::cout << *i << ' ';
}
T
被推导为std::vector<int>
,因此您试图将std::vector<int>::iterator
(v.begin()
的结果)转换为std::vector<std::vector<int>>::const_iterator
(i
的类型),这不是有效的转换。
相反,只需制作一个更专业的模板函数:
template <typename T>
void print_vector(std::vector<T>& v) {
// as before
}
如果您想将std::vector<T>::const_iterator i
传递给任何可迭代的向量,请将其简单地替换为T::const_iterator i
;如果您希望它只针对任何类型的向量,则可以用void print_vector(std::vector<T>& v)
适当地专门化它。
如果你现在运行一个替换,你会看到你给了一个向量,创建了一个类型之外的向量,从而得到了向量的向量。
此外,GCC 4.8和4.9改进了消息,并添加了更精确的错误插入符号。如果你不能移动编译器(这是可以理解的),那么你可以随时将这样的小片段提供给ideone.com这样的在线编译器。在4.8中,错误很可能会更加简洁易读。
哦,如果你可以访问C++11的功能(我不记得是什么在4.7中实现的),你可以自动进行这些类型声明,并使用cbegin()之类的东西,而不是开始获取类型解析来选择const_iterator,而不是普通的const_iteror。如果你正在学习模板,并且没有工作环境限制,我强烈建议你使用C++11和更新的GCC,这会让你更容易上手。
您正确地调用了函数。但随后您混淆了模板参数(容器的类型)和容器元素类型。
不管怎样,它没有理由不是const
。
因此,它应该是这样的:
template <typename T> void print_vector(const T& v) {
for(typename T::const_iterator i = v.begin(); i != v.end(); ++i)
std::cout << *i << ' ';
}
或者使用标准库和lambdas:
template <typename T> void print_vector(const T& v) {
using std::begin; // Using ADL for begin and end to support raw arrays
using std::end;
std::for_each(begin(v), end(v), [](auto&& x){std::cout<<*i<<' ';});
}
或者使用auto
和循环范围(我最喜欢):
template <typename T> void print_vector(const T& v) {
for(auto&& i : v)
std::cout << *i << ' ';
}
或者使用C++1z(预计2017年):
void print_vector(const auto& v) {
for(auto&& i : v)
std::cout << *i << ' ';
}
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 函数调用C++中的参数太少
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 返回指向对象的指针的函数调用是否为 prvalue?
- C++ 如何重载 [] 运算符并进行函数调用
- 代码的效率. 转到和函数调用
- 是同一作用域的函数部分中的函数调用
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 类型擦除的std::function与虚拟函数调用的开销