当从函数返回时,为什么我不能使用带数组的基于范围的循环?

时间:2017-10-12 15:48:29

标签: c++ loops oop pointers

我正在用C ++制作一个数独游戏,以更周密地改进和学习SFML,但是我遇到了基于范围的循环的问题。

我有一个像这样的数组:

Table Tables[9];

当我像这样循环它们时:

for(auto table: Tables){
    //do stuff
   }

没有问题。每个表都有一个子字段数组,如此

Field fields[9];

应该使用getter访问

Field *Table::getFields() {
    return fields;
}

但是当我尝试用

完成所有操作时
for(auto table: Tables){
    for(auto field: table.getFields()) {
        //do stuff
    }
}

我收到错误“Field *”不是有效的范围类型。如何返回数组以使其可循环?

另外:我测试了Tables[i].getFields()[f].doStuff并且它工作得很好,所以我相信数组会被返回。

2 个答案:

答案 0 :(得分:3)

Field fields[9];

Field *Table::getFields() {
    return fields;
}

您的代码的问题在于您返回一个原始指针(Field*),它不知道它所指向的数组的 size

如果你想在这种情况下使用基于范围的for循环,你必须返回更高级别的东西,其范围是明确定义的。

例如,您可以使用std::array(这是一个非常小的原始C风格数组包装器),并返回对它的引用(或const引用,以进行只读访问)。

e.g。

// Instead of Field fields[9]
std::array<Field, 9> fields;

另一种方法是使用 std::vector<Field> ,其开销比std::array更多,但也提供了更多功能,而且功能更多。 同样,您可以定义vector<Field>数据成员,并从vector<Field> &成员函数返回getFields(或const vector<Field>&进行只读访问)。

答案 1 :(得分:0)

您无法使用基于范围的循环的原因是您没有返回数组。严格来说,您将指针返回到数组的第一个元素。在C++中传递或返回数组时,它们会“衰减”为指向其第一个元素的指针。

要解决此问题,您可以将引用返回到数组,如下所示:

struct Table
{
    std::string stuff() const { return "stuff"; }
};

Table tables[9];

auto& getTables()
{
    return tables;
}

int main()
{
    for(auto table: tables)
        std::cout << table.stuff() << '\n';
}

我在这里使用auto&因为返回对数组的引用的语法有点复杂:

Table (&getTables())[9] // using auto is nicer
{
    return tables;
}

当然,根据您使用std::vector<Table>std::array<table>的情况,可以选择更好的选项,并返回对这些选项的引用。