I am trying to overload the =operator on line 9 in the code below:
void searchContact(vector<Person> &people){
string searchTerm;
vector<Person>::iterator it;
cout << endl;
cout << "Enter search term: ";
getline(cin, searchTerm);
it = find(people.begin(), people.end(), searchTerm);
if (it != people.end()){
cout << "Element found in: " << *it << '\n';
}else{
cout << "Element not found\n";
}
}
My approach is this:
int data;
Person& operator=(Person& a) { return a; }
Person& operator=(int a) {
data = a;
return *this;
}
I am getting this error:
class.cpp:129:30: error: ‘Person& operator=(Person&)’ must be a nonstatic member function
Person& operator=(Person& a) { return a; }
^
class.cpp:130:26: error: ‘Person& operator=(int)’ must be a nonstatic member function
Person& operator=(int a) {
What is wrong with my approach, or am i doing it all wrong from the beginning?
First, you are overloading the wrong operator. std::find() uses operator== (comparison) instead of operator= (assignment). And, given that you are passing a std::string to std::find(), you need an operator== that takes a std::string as input, not a Person.
Second, you are trying to implement the operators as unary operators, which means they MUST be non-static members of your Person class. The compiler is complaining that they are not.
Third, if std::find() finds a match, you are passing *it to std::cout, so you need an overloaded operator<< that takes a Person for output.
Try something like this:
class Person
{
public:
...
bool operator==(const string &rhs) const
{
// compare members of *this to rhs as needed...
return ...; // true or false
}
/* alternatively:
friend bool operator==(const Person &lhs, const string &rhs)
{
// compare members of lhs to rhs as needed...
return ...; // true or false
}
*/
friend ostream& operator<<(ostream &out, const Person &p)
{
// output p to out as needed...
return out;
}
...
};
Then your search code will work:
void searchContact(vector<Person> &people)
{
cout << endl;
cout << "Enter search term: ";
string searchTerm;
getline(cin, searchTerm);
vector<Person>::iterator it = find(people.begin(), people.end(), searchTerm);
if (it != people.end()) {
cout << "Element found in: " << *it << '\n';
} else {
cout << "Element not found\n";
}
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Person{
private:
int data;
public:
Person(int data)
{
this->data = data;
}
int getData()
{
return data;
}
friend bool operator==( const Person &lhs, const int rhs);
};
bool operator== ( const Person &lhs, const int rhs )
{
return lhs.data == rhs;
}
void searchContact(std::vector<Person> &people){
int searchTerm = 1;
vector<Person>::iterator it;
it = find(people.begin(), people.end(), searchTerm);
if (it != people.end()){
cout << "Element found in: " << it->getData() << '\n';
}else{
cout << "Element not found\n";
}
}
int main(int argc, char **argv)
{
std::vector<Person> list1 = {1, 2, 3, 4};
std::vector<Person> list2 = {1, 2, 3, 5};
std::vector<Person> list3 = {1, 3, 7, 6, 9, 5, 2, 4};
searchContact(list1);
searchContact(list2);
searchContact(list3);
}
i don't know what do you want. please show your full code and tell what do you want.
if you want to find element in vector, you can write like this(not string. if ou want to find string, just change int to string and get data with cin or etc)
Related
I have created a function that should edit the attributes of a class stored in a database. However, the vector insert function doesn't work as I expected. Could someone please suggest how I should implement the insert vector function to fill the hole I have made?
Whenever I implement it, this pops up:
Process finished with exit code -1073741819 (0xC0000005)
Code:
using namespace std;
int Natobase::counter = 0;
Natobase::Natobase(string n, string ci, string co, int ri, int tan, int pla, int lan)
: name(n), city(ci), country(co), rifles(ri), tanks(tan), planes(pla), launcher(lan) {};
Natobase::Natobase(string init) : Natobase("20thDiv", "Kuldiga", "Latvia", 100, 50, 75, 32) {};
std::ostream &printnames(std::ostream &pr, Natobase &pro) {
pr << "\nID:" << pro.ID << "\nName:" << pro.name;
return pr;
}
std::istream &operator>>(std::istream &re, Natobase &product) {
std::cout << "Enter the name of the base: \n";
re >> product.name;
std::cout << "Enter the city where it is located: \n";
re >> product.city;
std::cout << "Enter the country where it is located: \n";
re >> product.country;
std::cout << "Enter the number of guns held: \n";
re >> product.rifles;
std::cout << "Enter the number of tanks stationing: \n";
re >> product.tanks;
std::cout << "Enter the number of planes stationing: \n";
re >> product.planes;
std::cout << "Enter the number of launchers stationing: \n";
re >> product.launcher;
product.get_counter();
product.ID = product.counter;
return re;
}
**void Database::EditDB() {
Natobase nato;
int editt;
cout << "Enter the number of the base that you want to change:\n";
std::cout << "The bases are:\n";
printids();
cin >> editt;
auto iter = std::find_if(std::begin(DbMain), std::end(DbMain), [&](Natobase& nb)
{ return nb.get_ID() == editt; });
if (iter != DbMain.end())
{
DbMain.erase(iter);
cout << "\nPlease enter the input of the base one more time" << endl;
cin >> nato;
DbMain.insert(DbMain.begin() + iter->get_ID(), nato);
cout << "\nSuccess";
}
}**
Header file included:
//
// Created by Stasd on 28/04/2022.
//
//Stanislaw Dutkiewicz 263509
#ifndef OOPLABPROJECT_NATOBASE_H
#define OOPLABPROJECT_NATOBASE_H
#include <string>
#include <vector>
#include "Natobase.h"
class Natobase {
friend std::ostream &tosave(std::ostream &, const Natobase &);
friend std::istream &toim(std::istream &, Natobase &);
friend std::ostream &printnames(std::ostream &, Natobase &);
friend std::istream &operator>>(std::istream &, Natobase &);
public:
Natobase() = default;
Natobase(std::string n, std::string ci, std::string co, int ri, int tan, int pla, int lan); //read-only
Natobase(std::string init); //initialisation
const std::string &get_name() const { return this->name; }
const std::string &get_city() const { return this->city; }
const std::string &get_country() const { return this->country; }
const int &get_rifle() const { return this->rifles; }
const int &get_tanks() const { return this->tanks; }
const int &get_planes() const { return this->planes; }
const int &get_launch() const { return this->launcher; }
const int &get_ID() const { return this->ID; }
friend class Database;
private:
std::string name;
std::string city;
std::string country;
int rifles;
int tanks;
int planes;
int launcher;
static int counter;
int ID;
static int get_counter()
{
counter++;
return counter;
};
};
std::ostream &tosave(std::ostream &, const Natobase &); //save data into txt file
std::istream &toim(std::istream &, Natobase &);// to read the data from txt file
std::ostream &printnames(std::ostream &, Natobase &); //used for edit and remove function in Database class
std::ostream &operator<<(std::ostream &, const Natobase &); //input attributes
std::istream &operator>>(std::istream &, Natobase &); //output attributes
/////////////////////////
////////////////////////
class Database {
public:
Database() = default;
void print_data();
void read_data();
void saveDB();
void openDB();
void EditDB();
void RemoveDB();
void printids();
void compare();
private:
std::vector<Natobase> DbMain;
};
#endif //OOPLABPROJECT_NATOBASE_H
From this erase reference:
Invalidates iterators and references at or after the point of the erase, including the end() iterator.
After you called erase the iterator iter is no longer valid, it can't be used anymore.
If you need to use data from it you need to copy it first before you call erase.
You also need to use the iterator that erasereturns if you want to continue your loop.
I have been having trouble with the last bit of my code. I declared an instance of Grocery using the parameterized, copy and default constructor and made use of the operator= and operator<< overload. I am now having difficulty trying to create a dynamic array. I have to fill the array with the contents of my text filefileName.txt.
When I run this code I keep getting this one error:
Error C2679 binary '>>': no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion). Can I not access the setters in the array using >> (w/o overloading)? If not, how can I?
int main()
{
// Parameter - Instance 1
Grocery g1("NA", 0, "NA");
g1.setName("Milk");
g1.setQuant("1");
g1.setUnit("Bottle");
Grocery g2(g1); // Calls copy constructor
// Default constructor - Instance 3
//Grocery g3();
// Operator =
Grocery g4;
cout << "Operator = Running" << endl;
g4 = g2;
cout << g4.getName() << endl;
cout << g4.getQuant() << endl;
cout << g4.getUnit() << endl << endl;
// Operator <<
cout << "Operator<< Running" << endl;
Grocery g5("Salt", "1", "Bag");
cout << g5 << endl;
//cout << g5.getName();
//cout << g5.getQuant();
//cout << g5.getUnit();
// Dynamic Array of Grocery
Grocery* groceryArray;
groceryArray = new Grocery[3];
ifstream inputFile;
inputFile.open("fileName.txt");
for (int i = 0; i < 3; i++)
{
inputFile >> groceryArray[i].setName; // LINE ERROR IS HERE**
}
inputFile.close();
delete[]groceryArray;
return 0;
}
//Grocery.h
#pragma once
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Grocery
{
private:
string* m_name;
string* m_quant;
string* m_unit;
public:
Grocery(); // Default constructor
Grocery(string n, string q, string u); // Parametered constructor
~Grocery(); // Destructor
Grocery(const Grocery& rhs); // Copy constructor
Grocery& operator=(const Grocery& rhs); // Operator=
friend ostream& operator<<(ostream& out, const Grocery& rhs); //Operator>>
string getName();
void setName(string n);
string getQuant();
void setQuant(string q);
string getUnit();
void setUnit(string u);
};
#include "Grocery.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
Grocery::Grocery() // Default constructor
{
m_name = new string;
m_quant = new string;
m_unit = new string;
*m_name = "N/A";
*m_quant = "NA";
*m_unit = "N/A";
}
Grocery::Grocery(string n, string q, string u) // Parameterized constructor
{
//cout << "3 parameter constructor called" << endl;
// Initializes member variables as parameter variables
m_name = new string;
m_quant = new string;
m_unit = new string;
*m_name = n;
*m_quant = q;
*m_unit = u;
}
Grocery::Grocery(const Grocery& rhs) // Copy
{
m_name = new string;
m_quant = new string;
m_unit = new string;
*m_name = *rhs.m_name;
*m_quant = *rhs.m_quant;
*m_unit = *rhs.m_unit;
}
Grocery& Grocery::operator=(const Grocery& rhs) // Operator=
{
// Performs deep copy of other Grocery instance
if (this == &rhs)
return *this;
*m_name = *rhs.m_name;
*m_quant = *rhs.m_quant;
*m_unit = *rhs.m_unit;
return *this;
}
ostream& operator<<(ostream& out, const Grocery& rhs) // Operator<<
{
out << *rhs.m_name << endl << *rhs.m_quant << endl << *rhs.m_unit << endl;
return out;
}
Grocery::~Grocery() // Destructor
{
delete m_name;
delete m_quant;
delete m_unit;
*m_name = nullptr;
*m_quant = nullptr;
*m_unit = nullptr;
}
string Grocery::getName() { return *m_name; }
void Grocery::setName(string n) { *m_name = n; }
string Grocery::getQuant() { return *m_quant; }
void Grocery::setQuant(string q) { *m_quant = q; }
string Grocery::getUnit() { return *m_unit; }
void Grocery::setUnit(string u) { *m_unit = u; }
First things first: groceryArray[i].setName is a method of Grocery which makes the statement **inputFile >> groceryArray[i].setName; highly nonsensical.
What you want instead is to first read in a string and then change the name like so:
std::string name;
**inputFile >> name;
groceryArray[i].setName(name);
I have 2 classes, I make an object from the second class (I pass the filename as an argument). It should print the contents of the file which contains the following data in the following format:
A.Yordanov 1234567819
S.Todorov 3456789120
D.Lazarov 2569789054
P.Pavlov 4329549823
M.Kalinova 2367892343
B.Georgiev 659045324
I have overloaded the << operator but I when I try to cout << cty2 nothing appears on the console even though I have put the file in the same directory?
// OOP_Homework.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <fstream>
#include <set>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
fstream f;
class CPerson {
string name;
string egn;
public:
CPerson(string n, string e) {
name = n;
egn = e;
}
friend bool operator<(CPerson p1, CPerson p2) {
if (p1.egn < p2.egn) {
return true;
}
return false;
}
friend bool operator==(CPerson p1, CPerson p2) {
if (p1.egn == p2.egn) {
return true;
}
return false;
}
friend ostream& operator<< (ostream o, CPerson pn) {
o << "Egn" << endl;
o << pn.egn << endl;
o << "Name:" << endl;
o << pn.name << endl;
}
friend istream& operator>> (istream is, CPerson p) {
is >> p.egn;
is >> p.name;
return is;
}
string getName() {
return name;
}
string getEgn() {
return egn;
}
void setName(string n) {
name = n;
}
void setEgn(string e) {
egn = e;
}
};
class CCity {
vector<CPerson> pr;
public:
CCity(string fl) {
f.open(fl, ios::out);
string name = "", fn = "";
while (!f.eof()) {
//формата на данните във файла е във вида:
//<име на студент> <факултетен номер>
cin >> name >> fn;
pr.push_back(CPerson(name, fn));
}
f.close();
}
//помощен getter за вектора pr;
vector<CPerson> getV() {
return pr;
}
friend ostream& operator<<(ostream& os, CCity& psn) {
vector<CPerson> ps = psn.getV();
for (auto x = ps.begin(); x != ps.end(); x++) {
os << x->getName() << endl;
os << x->getEgn() << endl;
}
return os;
}
vector<CPerson> getDuplicate() {
set<CPerson> temp;
vector<CPerson> duplicates;
for (auto i = pr.begin(); i != pr.end(); i++) {
for (auto x : pr) {
if (*i == x) {
temp.insert(*i);
}
}
}
for (auto j : temp) {
duplicates.push_back(j);
}
temp.clear();
//връщаме студентите с повтарящи се егн-та
return duplicates;
}
void removeDuplicates() {
sort(pr.begin(),pr.end());
pr.erase(unique(pr.begin(), pr.end()));
}
void removeVector(vector<CPerson> ob) {
for (auto i:ob) {
for (auto x = pr.begin(); x != pr.end(); x++) {
if (i == *x) {
pr.erase(x);
}
}
}
}
};
int main()
{
CCity cty2("persons.txt");
//cout << cty1 << endl;
cout << cty2 << endl;
return 0;
}
The code for your overload for operator<< should be
friend ostream& operator<< (ostream &o, const CPerson &pn) {
// ^ ^^^^^ ^
o << "Egn" << endl;
o << pn.egn << endl;
o << "Name:" << endl;
o << pn.name << endl;
return o; // since return type is ostream&
}
You should be passing the stream by reference and returning it once you've finished using it. Passing by-reference ensures that the same stream is used (unlike pass-by-value).
Another thing to note would be your CPerson p function arguments. These should be passed by-reference as well. With operator<<, your CPerson won't be modified, so we can keep it as const.
You may also want to watch out your operator>>. Again, istream is should be istream &is. With the CPerson p parameter, you will modify it, so you'll definitely want to be passing it as a reference.
friend istream& operator>> (istream &is, CPerson &p) {
// ^ ^
is >> p.egn;
is >> p.name;
return is;
}
In your other overloads, you should be using const CPerson &p as well. Moreover, your overloads for operator< and operator== don't need to be friended since they're not accessing any other class's private members. Thus,
bool operator<(const CPerson &p1, const CPerson &p2) {
if (p1.egn < p2.egn) {
return true;
}
return false;
}
bool operator==(const CPerson &p1, const CPerson &p2) {
if (p1.egn == p2.egn) {
return true;
}
return false;
}
You'll want to get used to passing your classes by-reference as it saves space (not having to copy-construct another instance of the class as passing by-value would do). It's thus, more efficient both space-wise and performance-wise to pass your classes by reference.
I am attempting to implement a std::list to replace a linked list in this assignment. I am not allowed to change the declarations and can only change code in the .cpp file. For the most part I am making progress but I am having trouble implementing this
std::ostream& operator<< (std::ostream& out, const Section& section);
namely when I try to create an iterator it fails. I've used the iterator elsewhere in the code so I don't understand why it's failing here, I believe it's because it's private but I'm not sure how to resolve the issue without changing the .h file which was explicitly prohibited:
std::ostream& operator<< (std::ostream& out, const Section& section)
{
// 1. print the section header
out << setw(8) << left << section.getCourse()
<< setw(6) << left << section.getCallNumber();
out << ": " << section.getNumberOfStudents() << " students\n";
// 2. collect the students, sort, and print
Student* students = new Student[section.getNumberOfStudents()];
{
int i = 0;
for ( auto pos = section.students.begin();
pos != section.students.end(); pos++)
{
students[i] = pos;
++i;
}
}
sort (students, students+section.getNumberOfStudents());
for (int i = 0; i < section.getNumberOfStudents(); ++i)
out << " " << students[i] << "\n";
out << flush;
return out;
}
students[i] = pos;
should be changed to
students[i] = *pos;
because you want to copy the Student the iterator references, not the iterator itself.
But why a dynamic array of Student rather than a std::vector<Student>? Currently you have a memory leak because you don't delete[] students;
Edit 1
Removed.
Edit 2
Other than that, all I can see that it wrong is a missing std:: in front of
sort (students, students+section.getNumberOfStudents());
this is assuming there is no custom sort method being used.
Edit 3
Going off the rails here:
students[i] = *pos;
copies a Student from the list into the dynamic array students. This could be expensive, so here is an alternative:
First the bits and pieces needed to prove this out: Required includes
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <functional>
a minimal Student class
class Student
{
std::string name;
public:
Student(std::string inname):name(inname)
{
}
const std::string & getname() const
{
return name;
}
friend bool operator<(const Student & a, const Student &b)
{
return a.name < b.name;
}
};
a minimal Section class
class Section
{
public:
std::list<Student> students;
};
a minimal outstream operator
std::ostream& operator<<(std::ostream& out, const Section& section)
{
A std::vector instead of an array, and a vector of constant references so we don't have to copy the students.
std::vector<std::reference_wrapper<const Student>> students;
Store references in the vector. Probably could do a one liner with std::copy and std::back_inserter, but this is getting a bit too much to absorb for one example.
for (const auto & student: section.students)
{
students.push_back(std::ref(student));
}
Sort the vector
std::sort(students.begin(), students.end());
print the vector
for (const auto & student: students)
{
out << student.get().getname() << " ";
}
return out;
}
and one main to rule them all and in the darkness bind them
int main()
{
Section s;
s.students.emplace_front("Tom");
s.students.emplace_front("Dick");
s.students.emplace_front("Harry");
std::cout << s;
}
And all in one easy to cut-n-paste block:
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <functional>
class Student
{
public:
std::string name; // this is me being lazy. name should be private
Student(std::string inname):name(inname)
{
}
const std::string & getname() const
{
return name;
}
friend bool operator<(const Student & a, const Student &b)
{
return a.name < b.name;
}
};
class Section
{
public:
std::list<Student> students;
};
std::ostream& operator<<(std::ostream& out, const Section& section)
{
std::vector<std::reference_wrapper<const Student>> students;
// store references in the `vector`.
for (const auto & student: section.students)
{
students.push_back(std::ref(student));
}
// Sort the `vector`
std::sort(students.begin(), students.end());
// print the `vector`
for (const auto & student: students)
{
out << student.get().getname() << " ";
}
return out;
}
int main()
{
Section s;
s.students.emplace_front("Tom");
s.students.emplace_front("Dick");
s.students.emplace_front("Harry");
std::cout << s;
}
Or do what Remy suggested and use a std::vector<Student *> and a custom comparator to dereference the pointers for std::sort.
As others have stated, the error is because you are not dereferencing the iterator when populating your students[] array:
students[i] = pos; // <-- should be *pos instead!
I would suggest an alternative approach that should be faster and more efficient:
std::ostream& operator<< (std::ostream& out, const Section& section)
{
// 1. print the section header
out << setw(8) << left << section.getCourse()
<< setw(6) << left << section.getCallNumber();
out << ": " << section.getNumberOfStudents() << " students\n";
// 2. collect the students, sort, and print
std::vector<const Student*> students;
students.reserve(section.getNumberOfStudents());
for ( auto pos = section.students.cbegin();
pos != section.students.cend(); ++pos)
{
students.push_back(&(*pos));
}
sort (students.begin(), students.end(),
[](const Student *a, const Student *b) { return (*a < *b); }
);
for ( auto pos = students.cbegin();
pos != students.cend(); ++pos)
{
out << " " << *(*pos) << "\n";
}
out << flush;
return out;
}
I appreciate all your answers. Ended up being a much more basic issue. I had to implement the Section iterators to return student iterators.
Section::iterator Section::begin() {
return students.begin();
}
Section::const_iterator Section::begin() const {
return students.begin();
}
Section::iterator Section::end() {
return students.begin();
}
Section::const_iterator Section::end() const {
return students.begin();
}
This question already has answers here:
How can I use cout << myclass
(5 answers)
Closed 4 months ago.
I've been reading questions here for an hour or two regarding this error I'm getting and most of them forgot to #include string (which I had already done), or to overload the << operator.
Here's the code in question:
void Student::getCoursesEnrolled(const vector<Course>& c)
{
for (int i = 0; i < c.size(); i++)
{
cout << c[i] << endl;
}
}
And the error I'm getting:
Error: No operator matches these operands
operand types are: std::ostream << const Course
All I'm trying to do is return the vector. I read about overloading the << operator but we haven't learned any of that in class so I'm assuming there is another way of doing it?
I appreciate your time!
All I'm trying to do is return the vector.
Not quite; you're trying to print it using cout. And cout has no idea how to print a Course object, unless you provide an overloaded operator<< to tell it how to do so:
std::ostream& operator<<(std::ostream& out, const Course& course)
{
out << course.getName(); // for example
return out;
}
See the operator overloading bible here on StackOverflow for more information.
The problem is that operator << is not overload for type Course objects of which you are trying to output in statement
cout << c[i] << endl;
You need to overload this operator or write your own function that will output an object of type Course in std::ostream
For example let assume that below is a definition of class Course
class Course
{
private:
std::string name;
unsigned int duration;
public:
Course() : duration( 0 ) {}
Course( const std::string &s, unsigned int n ) : name( s ), duration( n ) {}
std::ostream & out( std::ostream &os ) const
{
return ( os << "Course name = " << name << ", course duration = " << duration );
}
};
When you can write
std::vector<Course> v = { { "A", 1 }, { "B", 2 }, { "C", 3 } };
for ( const Course &c : v ) c.out( std::cout ) << std::endl;
Instead member function out you can overload operator <<. For example
class Course
{
private:
std::string name;
unsigned int duration;
public:
Course() : duration( 0 ) {}
Course( const std::string &s, unsigned int n ) : name( s ), duration( n ) {}
friend std::ostream & operator <<( std::ostream &os, const Course & c )
{
return ( os << "Course name = " << c.name << ", course duration = " << c.duration );
}
};
and use it as
std::vector<Course> v = { { "A", 1 }, { "B", 2 }, { "C", 3 } };
for ( const Course &c : v ) std::cout << c << std::endl;
The stream operator << is used to "output" some representation of that object. If you don't want to overload the operator yet just pick some property to output instead:
for (int i = 0; i < c.size(); i++)
{
cout << c[i].Name << endl; // assuming Name is a property of Course
}
When you DO overload the operator you just decide then what the proper representation of a Course is:
ostream& operator<< (ostream &out, Course &c)
{
out << c.Name "(" << c.Description << ")";
return out;
}
Your Course class needs to implement an operator:
class Course
{
public:
/*
* Your code here
*/
// Probably missing this:
friend std::ostream& operator << (std::ostream& os, const Course& course)
{
os << course.name(); // etc..
return os;
};
}; // eo class Course
Since you haven't yet learned to overload operator<<, what you can do instead is to print each member of your Course class. You haven't posted the definition of Course, but perhaps it's something like this:
class Course
{
public:
int get_number() { return _number; }
const std::string& get_name() { return _name; }
private:
int _number;
std::string _name;
};
then you can say:
void Student::getCoursesEnrolled(const vector<Course>& c)
{
for (int i = 0; i < c.size(); i++)
{
cout << c[i].get_number() << " "
<< c[i].get_name() << std::endl;
}
}
Your problem is this particular part:
cout << c[i]
In your case c[i] is an object of type Course as dvnrrs correctly pointed out. So either:
implement the overloaded << operator for your object OR
if your Course object is in someway a typedef to a primitive try explicitly casting it to a string type (or similar)