使用C++11中的范围循环遍历指向vector的指针

11

我刚刚编译了GCC 4.6.0,并想尝试其中的新功能,首先是范围-based for 循环。
我想要改变的第一个循环是迭代指向 std::vector 中的指针。我更改了代码以使用新语法,但它并没有编译成功。

我尝试替换另一个循环,它是在一个 std::vector 的结构体上,它编译和运行得非常完美。

这里有一个简短的测试代码,用来展示我的问题:

#include <vector>
#include <iostream>

int main()
{
    std::vector< int > values;
    
    values.push_back(2);
    values.push_back(5);
    values.push_back(8);
    values.push_back(13);
    values.push_back(17);
    
    for (int &n : values)
    {
        std::cout << n << "\n";
    }
    
    std::vector< int* > pointers;
    
    pointers.push_back(new int(2));
    pointers.push_back(new int(5));
    pointers.push_back(new int(8));
    pointers.push_back(new int(13));
    pointers.push_back(new int(17));
    
    for ((int*) &p : values)
    {
        std::cout << (*p) << "\n";
    }
    
    for( unsigned int i = 0; i < pointers.size(); ++i)
    {
        delete pointers[i];
    }
    
    return 0;
}

当我尝试编译它(是的,我把-std=c++0x作为g++的参数)时,出现以下错误:

main.cpp|27|error: found ‘:’ in nested-name-specifier, expected ‘::’

如果我注释掉27-30行,则可以编译通过。

我做错了什么?指针引用的声明语法不对吗?
或者使用基于范围的for循环有所限制吗?


1
可能应该移动到 Stack Overflow 上。 - Doug T.
2
@Doug:同意……如果问题包含源代码而不是一个微小的URL,那也会有所帮助。 - jprete
2个回答

21
for ((int*) &p : values)

这是错误的。(int*) 仅为表达式,因此您需要至少使用 int*&(不带括号,这会产生一个表达式 - 即“不是类型名”)来使其正确。个人更喜欢使用自动类型推断(auto或auto&)。

您可以执行以下操作:

for (auto p : values) // here p is a pointer, a copy of each pointer
或者
for (auto& p : values ) // here p is a non-const reference to a pointer
或者
for ( int* p : values ) // here p is a copy of each pointer

或在通用代码中:

for ( auto&& p: values ) // p is either a const reference to what is in values, or a non-const reference, depends on the context

所以在这种情况下,对于 std::vector<int*> 中的 auto 将产生 int*,而 auto& 将产生 int*&。有道理。但是为什么你会想要 int*& 呢?哦,我猜前者实际上正在复制内存,而后者则不是? - Andrew
1
@Andrew 根据情况而定,有时您想确保所获得的类型是您想要的,或者您想以某种方式进行转换。在这里,auto是一个很好的默认值,但是如果使用概念的话会略微更好一些(C++20):for( std::integral auto* p : values) 确保您获得的指针是指向看起来像整数的内容。 - Klaim

1

我认为你在那里想要迭代“指针”而不是“值”...


很遗憾只能接受一个答案。你也是正确的,我写值而不是指针是愚蠢的,但Klaim的评论更详细,并显示了括号的错误。无论如何,非常感谢! - Attila

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接