For each cycle, only the first line of the C ++ array is required

I am using C ++ 14 and trying to create for each loop that prints each row of an array. I get an error message:

user.cpp: 12: 34: error: invalid initialization of a link of type std :: string & {aka std :: basic_string &} from an expression of type 'char

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

When I change std :: string to auto in the foreach loop, it works, but str becomes the individual characters of the first line in the favs array. My code is as follows:

user.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; }; 

user.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"; } } 
+6
source share
2 answers

When you u->favs for u->favs , you get std::string& , and the range is based on what it then starts to repeat after that string one character at a time. Therefore, when you auto you see individual characters from the first line, and when you try to associate this character with string& , you get a compilation error.

You cannot get a range based on working with a pointer type because it does not know how many objects your pointer points to. If you make the following changes to your code to declare favs as an array of static size, then your code will work.

Change the class definition to

 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 }; 

If you need an array with dynamic size, use std::vector<std::string> instead, and your loop will work.

+5
source

If you want to use a range-based loop, there are two ways:

1) std::string favs[n];

range-based loop works with constant size arrays

2) std::vector<std::string> favs

Range Based Contour

works with objects that have implemented start / end, and STL containers do this.

 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) If favs will be the main array of your class ... and you want to try the begin / end idea, here is how you do it:

 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; 
+1
source

All Articles