Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么我不能创建这样的模板函数?_C++_Templates_Vector - Fatal编程技术网

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());