【问题标题】:For each loop only takes first string of array C++对于每个循环只需要数组 C++ 的第一个字符串
【发布时间】:2016-05-24 07:48:07
【问题描述】:

我正在使用 C++14 并尝试为每个循环创建一个打印出数组的每个字符串的循环。我得到错误:

user.cpp:12:34:错误:从“char”类型的表达式中对“std::string& {aka std::basic_string&}”类型的引用进行无效初始化

for(std::string &str : *(u->favs)){

当我在 foreach 循环中将 std::string 更改为 auto 时,它可以工作,但 str 成为 favs 数组中第一个字符串的单个字符。 我的代码如下:

用户.h

class User{
    private:

    public:
        User(){
            favs = new std::string[5]{std::string("Hello"), std::string("how"), std::string("are"), std::string("you"), std::string("?")};
        }

        ~User(){
            delete[] favs;
        }

        std::string lName;
        std::string fName;
        int age;
        std::string *favs;
};

用户.cpp

#include <iostream>
#include "user.h"

void create(User *u){   
    std::cout << "Please enter first name: ";
    std::cin >> u->fName;
    std::cout << "Please enter last name: ";
    std::cin >> u->lName;
    std::cout << "Please enter age: ";
    std::cin >> u->age;

    for(std::string &str : *(u->favs)){
        std::cout << str << std::endl;
    }

    std::cout << "\n";
}

main.cpp

#include <iostream>
#include <string>
#include "user.h"       

int main(){
    std::string command;
    User user;
    std::cout << "bp1: " << user.favs->size() << std::endl;
    while(true){
        std::cout << "Please enter a command (Create, Update, View, Favorites, or Quit): ";
        std::cin >> command;
        if(command == "Create"){
            create(&user);
        } else if(command == "Update"){
            update(&user);
        } else if(command == "View"){
            view(&user);
        } else if(command == "Favorites"){
            //favorites(&user);
        } else if(command == "Quit"){
            break;
        } else std::cout << "Please input a valid command.\n";
    }
}

【问题讨论】:

  • 另外,user.favs的大小是数组第一个字符串的大小,而不是数组的元素个数

标签: c++ arrays string c++14


【解决方案1】:

当您取消引用 u-&gt;favs 时,您会得到一个 std::string&amp;,然后基于范围的 for 开始一次迭代该 string 一个字符。这就是为什么当您 auto 看到第一个字符串中的单个字符时,当您尝试将该字符绑定到 string&amp; 时会出现编译错误。

你不能得到一个基于范围的指针类型,因为它无法知道你的指针指向多少个对象。如果您对代码进行以下更改以将 favs 声明为静态大小的数组,那么您的代码将起作用。

将您的类定义更改为

using namespace std::string_literals;  // allows use of operator""s (user defined literal)
class User
{
public:
    User()
    : favs{{"Hello"s, "how"s, "are"s, "you"s, "?"s}}  // use operator""s
    {}

    // no need for a destructor definition

    std::string lName;
    std::string fName;
    int age;
    std::array<std::string, 5> favs;  // statically sized array
};

如果您需要动态大小的数组,请改用std::vector&lt;std::string&gt;,您的循环仍然可以工作。

【讨论】:

  • 如果您想快速尝试使用向量而不是基本数组,如果您直接将std::string favs[5]; 从他的答案换成std::vector&lt;std::string&gt; favs;,@Praetorian 的答案也适用于向量的初始化列表。
  • 非常正确,但我不愿支持推广 C 数组的答案,尤其是与其他现代 C++ 结构结合使用时。
  • @ildjarn 但是std::array 与普通的 C 数组相比,打字要多得多 :)
【解决方案2】:

如果你想使用基于范围的循环,有两种方法:

1) std::string favs[n];

基于范围的循环适用于具有恒定大小的数组

2)std::vector&lt;std::string&gt; favs

基于范围的循环适用于已实现开始/结束的对象,而 STL 容器会这样做。

class User{
    public:
        User() : favs {"Hello", "how", "are", "you", "?"} { }
        std::vector<std::string> favs;
};

for(std::string& str : u->favs)
    std::cout << str << std::endl;

3) 如果favs 将成为您班级的主要数组...并且您想尝试开始/结束的想法,请按照以下方式进行:

class User
{
public:
    std::string *favs;
    int favs_size;
    User()
    {
        favs_size = 5;
        favs = new string[favs_size];
    }
    ~User() { delete[] favs; } 

public:
    std::string* begin() { return favs; }
    std::string* end() { return favs+favs_size ; }
};

User u;
for(std::string &str : u)
    std::cout << str << std::endl;

【讨论】:

    猜你喜欢
    • 2015-01-10
    • 2018-12-12
    • 2015-01-16
    • 1970-01-01
    • 2014-05-30
    • 2020-01-20
    • 2014-08-27
    • 2011-12-14
    • 1970-01-01
    相关资源
    最近更新 更多