Help with Object of your Affections

Hey guys. I’m stuck on the Object of your Affections project. (https://www.codecademy.com/courses/learn-c-plus-plus/projects/cpp-dating-profile)

I am getting stuck on step 10.

app.cpp

#include <iostream>
#include "profile.hpp"
#include <vector>

int main() {

 Profile sam("sam", "dancing");

 sam.view_profile();

}

profile.hpp

#include <vector>

#include <string>

class Profile{

private:

std::string name;

int age;

std::string city;

std::string country;

std::string pronouns;

std::vector<std::string> hobbies;

public:

Profile(std::string new_name, std::string new_hobbies);

void add_hobby(std::string new_hobby);

std::string view_profile();

};

profile.cpp


#include <iostream>
#include "profile.hpp"


Profile::Profile(std::string new_name, std::string new_hobbies)

:name(new_name), hobbies(new_hobbies)
{

}

std::string Profile::view_profile(){
  std::cout << name;
  std::cout << hobbies;
 
}



void Profile::add_hobby(std::string new_hobby){


hobbies.push_back(new_hobby);
  
}

This is the error I keep getting.

A little background. I’m a game developer, and I make special effects. I’m trying to learn c++ to be a more rounded and technical game developer as well as make my own projects. SO i decided to start learning C++ on my own here at codecademy, so I can get the basics down. Right now Classes have got me stumped apparently.

You have std::vector<std::string> hobbies, but the << ostream operator doesn’t have behavior defined for the vector<string> type (that is what the error does say in the very beginning (error: no match for << and vector<basic_string> etc)).

Ok, that’s the error. Now what do you do? That’s really up to what you need.

  • For debugging purposes I highly recommend either getting used to an IDE debugger or GDB. This would allow you to “read” what’s in the vector when debugging.
  • If you need to print it in a special way according to your class, you can overload the << operator and define a special behavior. For example, maybe every time you cout << hobbies you might want it to display 1. hobby_a, 2. hobby_b, in some neat sort of way by default.
  • You just need to print the dang thing to standard out. Then you have to think, ok, vector is not printable, what’s the next best thing? Ah, the strings inside themselves. So you do a loop and print out each item in the loop.

One possible way

for (const auto& hobby: hobbies)
{
    std::cout << hobby << "\n";
}

A couple of things to note here. The use of const &, very important and useful to read up (exercise left to the reader). Also the use of auto. Also the use of range-based loops. Also the use of \n over std::endl. Happy hacking.

PS: Is this a bit much? Well C++ is a technical language, so it is good to sink in on details where other languages abstract it away. Particularly for games where performance is important it’s pretty nice to know what exactly is happening.

3 Likes

Thank you for you reply! Im’ not sure i copmletely undestand it though.

You have std::vector<std::string> hobbies, but the << ostream operator doesn’t have behavior defined for the vector<string> type (that is what the error does say in the very beginning (error: no match for << and vector<basic_string> etc)).

Are you saying I havent included Vector into my profile.cpp file?

Ok, that’s the error. Now what do you do? That’s really up to what you need.

So What I need is to print the hobbies that I put as parameters into the Profile constructor, and the add hobby method.

for (const auto& hobby: hobbies)
{
std::cout << hobby << “\n”;
}


A couple of things to note here. The use of const &, very important and useful to read up (exercise left to the reader). Also the use of auto. Also the use of range-based loops. Also the use of `\n` over std::endl. Happy hacking.   

I’m not sure what you mean by this part. I’m also not familiar with what (const auto& hobby: hobbies) means. I dont remember seeing that in the exercises ahead of this one.

Are you saying I havent included Vector into my profile.cpp file?

It’s not that you haven’t included it, it’s that cout << has no concept of how to print a vector. And hobbies is a vector.

So for example where you have

std::string Profile::view_profile(){
  std::cout << name;
  std::cout << hobbies; // this doesn't work
}

one very idiomatic solution would be (note also that I changed this to a void function. A void function is one where you don’t return anything. Unless you’re planning to return some string later…)

void Profile::view_profile(){
  std::cout << name;
  for (const auto& hobby: hobbies)
  {
    std::cout << hobby << "\n";
  }
}

if you want a more straightforward way to do it

void Profile::view_profile(){
  std::cout << name;
  for (int i = 0; i < hobbies.size(); i++)
  {
    std::cout << hobbies[i] << "\n";
  }
}

the reason these work is that you are now cout <<'ing something that the << operator does know how to deal with, strings.

Moreover the reason I mention those extra items is because C++ is vast. I know of no single book or course that properly covers a lot of what basic “decent” C++ is (since to do that is a heavy task). With this language I think you have to be enterprising in looking for resources. I always pick up something here, something there, etc. (in other words, sooner or later you have to be proactive, because it’s a hard language, not you specifically but anyone picking it up).

Youtube:
MIke Shah, TheCherno, Bo Qian, Jason Turner, Cppcon etc.

In terms of books I almost think reading about computer architecture and operating systems goes a long way to making sense of the tools that C++ can leverage. The specific ones are usually very technical (good) but might not be general enough in the beginning.

2 Likes

The idea that there is SO much to c++ is definetly something i’m struggling with. THere are so many ways to do a thing it seems, and that’s kicking my butt to say the least. However I’ll say I’ve definetly made progress.
Another problem I"m having is, I dont know what I dont know, nor do I know that I dont know it (lol) . So to combat that I’ve just been doing a lot of reading on sites like

C++ Class Member Functions.

or

https://www.learncpp.com/

I know I learn best when I’m messing things up, and putting it into context. My ultimate goal has been to make games. Unfortunately most of the resources I find describe and explain c++ in the technical terms. (which is cool) but they havent given me an actionable way to put it into context. So I’ve just been trying to figure out how to abstract my c++ knowledge into games(specifically Unreal) Its a process though, and I’m already much futher than I was a month ago.

To the topic at hand.
I understand now what you meant by cout << , not being able to out put a vector. SO I made the follwing changes in my profile.cpp (the one givine me issues).

#include <iostream>
#include "profile.hpp"


Profile::Profile(std::string new_name, std::vector<std::string> new_hobbies)  
//std::vector<std::string> is the new part

:name(new_name), hobbies(new_hobbies)
{}

void Profile::view_profile(){
  std::cout << name;

  for(int i = 0; i < hobbies.size(); i++){
    std::cout << hobbies[i] << "\n";

  };
  
}



void Profile::add_hobby(std::string new_hobby){


hobbies.push_back(new_hobby);
  
}

However, now the error i’m getting is

Something about how I have the Profile Method is wrong, but I cant tell what. As far as I know.
When the player inputs “new_hobbies” that SHOULD change hobbies to new hobbies and add it to the vector that I have in the class.
This one.

class Profile{

private:

std::string name;

int age;

std::string city;

std::string country;

std::string pronouns;

std::vector<std::string> hobbies;

public:

Profile(std::string new_name, std::string new_hobbies);

void add_hobby(std::string new_hobby);

void view_profile();

};

For games with C++ you really want to look at something like learning OpenGL (or SDL2 to start with something simpler), for which there are a ton of resources (warning, not for the feint of heart). I highly recommend Mike Shah’s channel for this. (completely free book and website tutorial https://learnopengl.com/)

In terms of your error, you need to have your constructor definition match your constructor declaratoin. So if you want

Profile::Profile(std::string new_name, std::vector<std::string> new_hobbies)  
//std::vector<std::string> is the new part

:name(new_name), hobbies(new_hobbies)
{}

then in the header file you have to change

Profile(std::string new_name, std::string new_hobbies);

to

Profile(std::string new_name, std::vector<std::string> new_hobbies);

Keep at it, you’re doing great. Don’t lose hope and keep your passion alive.

I was told to just jump into c++ because that’s what Unreal uses. Its tough so far, but I think i can manage.
I’m already in games, and I’m trying to add this to my repertoire. I’ve heard about Open GL though and think I’ll give it a try .
Thank you for the kind words by the way. I do appreciate the suppor.t I definitely need it. I’ve been learning for a month now. ANd that’s not long in the grand scheme of things. It definetly feels long though. Especially when you get stuck on something like “object of your affections” for a week. I’m having trouble identifying exactly what my problem is. Particularly, why I’m not seeing the solution.

in this case.

I’ve changed the header, and now the profile.cpp works correctly.

however, now my app.cpp is giving me an error that I don’t understand.

#include


#include "profile.hpp"

#include <vector>

int main() {

Profile sam("sam", "dancing");

sam.view_profile();

}

is getting.

So now i have two questions.
What are these errors, and how do I read them? Because to ME, it looks like its telling me that the class “Profile” is not spelled correctly.
IT’s also telling me that there is no matching function

my header looks like this


#include <vector>

#include <string>

class Profile{

private:

std::string name;

int age;

std::string city;

std::string country;

std::string pronouns;

std::vector<std::string> hobbies;

public:

Profile(std::string new_name, std::vector<std::string> new_hobbies);

void add_hobby(std::string new_hobby);

void view_profile();

};

And my CPP file looks like this (this is the one not failing)


#include <iostream>
#include "profile.hpp"


Profile::Profile(std::string new_name,std::vector<std::string> new_hobbies)

:name(new_name), hobbies(new_hobbies)
{}

void Profile::view_profile(){
  std::cout << name;

  for(int i = 0; i < hobbies.size(); i++){
    std::cout << hobbies[i] << "\n";

  };
  
}



void Profile::add_hobby(std::string new_hobby){


hobbies.push_back(new_hobby);
  
}

One thing you can do with compiler errors is look for the key terms (this comes with a bit of experience). I would google error no matching function call to c++ if I didn’t know this type of error.

For me, the error type is

no matching function call to (function signature)
(example of the call)

even without looking at the error itself, I’m expecting one of two things:

  • the function isn’t defined OR
  • the function is defined with a different signature (it takes in different types, etc)

So looking at the example you gave the function two string literals, ok.
But the constructor is written
Profile(std::string new_name, std::vector<std::string> new_hobbies);

… which means it expects a string as the first argument, but a vector of strings in the second argument.

An example for a function that takes in a vector as an argument. The function does nothing else.

void test(std::vector<std::string> x)
{
    ; //do nothing
}

int main()
{
     test({"testing"}); //legal
     test({"testing", "1", "2", "3"}); //still legal
     test({
        "testing",
        "one",
        "two",
        "three"
     }); //still legal, might be easier to read if you need to initialize a ton of values at once
     test("testing"); //illegal! no matching function call
     return 0;
}

Well that definetly cleared it up for me. I guess i cant make a function with two parameters. I was hoping I could

  1. put multiple string inputs for a vector.
  2. Put all that information in one method.

This is what I ended up getting, and this ended up working.

app.cpp


#include <iostream>

#include "profile.hpp"

#include <vector>

int main() {

Profile sam ("sam");

sam.add_hobby("new hobby");

sam.add_hobby("new hobby 2");

sam.add_hobby("new hobby 3");

sam.view_profile();

}

My Profile.cpp

#include <iostream>
#include "profile.hpp"


Profile::Profile(std::string new_name)

:name(new_name)
{}

void Profile::view_profile(){
  std::cout << name << "\n";

  for(int i = 0; i < hobbies.size(); i++){
    std::cout << hobbies[i] << "\n";

  };
  
}



void Profile::add_hobby(std::string new_hobby){

hobbies.push_back(new_hobby);
  
}

and this is the header file



#include <vector>

#include <string>

class Profile{

private:

std::string name;

int age;

std::string city;

std::string country;

std::string pronouns;

std::vector<std::string> hobbies;

public:

Profile(std::string new_name);

void add_hobby(std::string new_hobby);

void view_profile();

};

Not necessarily what i wanted. But it works!

You definitely can make a function with 2 or more parameters. Even variadic (variable number of paramaters, not very recommendable most times).

The key is that they have to have matching types.