C++ 为什么我不能创建这样的模板函数?
我尝试使用辅助函数打印向量,如下所示: 这行不通-C++ 为什么我不能创建这样的模板函数?,c++,templates,vector,C++,Templates,Vector,我尝试使用辅助函数打印向量,如下所示: 这行不通- template<class T> void print(const std::vector<T>& v) { std::vector<T>::const_iterator i; for (i = v.begin(); i != v.end(); i++) std::cout << *i << " "; std::cout <&l
template<class T>
void print(const std::vector<T>& v)
{
std::vector<T>::const_iterator i;
for (i = v.begin(); i != v.end(); i++)
std::cout << *i << " ";
std::cout << std::endl;
}
编辑:我明白了
但这是有效的-
template<class T>
void print(const std::vector<T>& v)
{
// changed std::vector<T> to std::vector<int>
std::vector<int>::const_iterator i;
for (i = v.begin(); i != v.end(); i++)
std::cout << *i << " ";
std::cout << std::endl;
}
我想问以下问题:
为什么第一个不起作用,第二个起作用?
为相同功能编写函数的替代方法有哪些?
另外,我不想在函数中更改任何元素。我想这可以通过使用每个算法来实现。但我不确定如何为它编写谓词。
你应该使用
typename std::vector<T>::const_iterator i;
使其按照编译器在错误消息中告诉您的方式工作
在第一种情况下,const_iterator是依赖于模板的名称,因此必须使用关键字来消除歧义
请按照Joachim Pileborg评论中的链接进行解释。std::vector::const_迭代器是一个依赖名称,您需要在前面添加typename:
typename std::vector<T>::const_iterator i;
或者这样写:
for (auto it = v.begin(); it != v.end(); ++it) {
std::cout << *it << " ";
}
或
什么是从属名称:
在某种程度上依赖于模板参数的名称。当然,任何显式包含模板参数的限定或非限定名称都是依赖的。此外,由成员访问操作符限定的限定名称。如果access运算符左侧的表达式类型取决于模板参数,则取决于->或。特别是,当b出现在模板中时,此->b中的b是一个从属名称。最后,当且仅当任何参数表达式具有依赖于模板参数的类型时,形式为identx,y,z的调用中的标识符ident是从属名称
为什么第一个不起作用,第二个起作用?
因为你忽略了错误
typename std::vector<T>::const_iterator i;
^^^Use typename
为相同功能编写函数的替代方法有哪些?另外,我不想在函数中更改任何元素。我想这可以通过使用每个算法来实现。但我不确定如何为它编写谓词。
如果您想使用intOh,可以用typename T替换class T,请尝试阅读错误消息。它实际上准确地说明了修复它所必须做的事情。@arne老实说,我编写模板重的代码已经有4年了,这是我第一次听到这种区别。我学会了在任何地方都喜欢类,因为它不能与表示非类型模板参数的typename混淆。恭喜。你做了一个文本截图。我更喜欢把我的同事当作成年人看待,并假设读者知道他们在读什么,也就是说,知道类和类型名在这种情况下是可以互换的。如果他们不这样做,他们就没有必要阅读这些代码,他们将继续阅读教模板的书,永远不会有任何混淆。所以第二种方法有效,因为类型名是在第二个函数中定义的,就像我显式编写类型一样?@mozart是的,因为在第二种方法中有int类型的元素向量,所以它的knownOr std::copy,,std::ostream_迭代器std::cout—有很多方法可以做到这一点,而无需详细说明迭代器类型。
typename std::vector<T>::const_iterator i;
^^^Use typename
struct foo{
void operator()(const int &i) const{
std::cout<<i<<" ";
}
}
for_each(v.begin(), v.end(),foo());