#include <functional>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
#include <boost/lambda/lambda.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost::lambda;
using namespace boost::multi_index;
using boost::multi_index_container;
using boost::lexical_cast;
struct student {
int no;
string name;
student(int _no, string _name) : no(_no), name(_name) { }
};
struct no {};
struct name {};
struct change_name {
change_name(const string& new_namex) : new_name(new_namex) {}
void operator()(student& stu) {
stu.name = new_name;
}
private:
string new_name;
};
int main()
{
typedef multi_index_container<
student,
indexed_by<
ordered_non_unique<tag<no>, member<student, int, &student::no>>,
ordered_non_unique<tag<name>, member<student, string, &student::name>>
>> student_set;
typedef student_set::index<no>::type student_set_no;
student_set students;
for (int i = 0; i < 10; ++i)
students.insert( student(i, "love student " + lexical_cast<string>(i)) );
student_set_no& no_index = students.get<no>();
student_set_no::iterator iter = no_index.find(3);
//suppose i want to change the name to "you",
no_index.modify(iter, change_name("you"));
//how could i do this with lambda expression ?
no_index.modify(iter, _1.name = "you");
cout << iter->name << endl;
return 0;
}
How could I change the name without defined the function operator class?
Thanks.
Related
I'm new to C++, coming from C. How do I access each element of each struct in a std::list created with the <list> library?
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <list>
#include <funcoes.h>
using namespace std;
typedef struct candidato{
int inscricao;
int idade;
int cod;
int nota;
}candidato_c;
int main(){
list<candidato_c> l;
startlist(l);
}
funcoes.h
void startlist (list<candidato_c>& lista1){
//How to access each element of each index?
}
This is how to to access each element
struct candidato {
int inscricao;
int idade;
int cod;
int nota;
};
int main(){
list<candidato> l;
startlist(l);
}
static void startlist(const std::list<candidato>& lista1) {
for (const candidato& c : lista1)
{
std::cout << c.cod << std::endl;
}
}
This is with Boost 1.72.0. What am I doing wrong? This is a simple example where I'm trying to create a struct named employee, which can be sorted by both id and name. I wanted to try this out before integrating multi_index into a larger more complex project, which requires a lot more indices. But I ran into errors using the code below. I compiled it using GCC 7.30. Since the error messages are complex and verbose, I left them off.
Here is the full source of the minimal example:
#include <iostream>
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
using namespace boost::multi_index;
struct employee {
employee(unsigned int id, std::string name)
: id(id), name(name)
{}
unsigned int id;
std::string name;
bool operator<(const employee& other) const noexcept {
return this->id < other.id;
}
};
struct indexedById {};
struct indexedByName {};
using EmployeeContainer = boost::multi_index_container
<
employee,
indexed_by<
ordered_unique<tag<indexedById>, identity<employee>>,
hashed_non_unique<tag<indexedByName>, member<employee, std::string, &employee::name>>
>
>;
int main()
{
EmployeeContainer mi;
auto& inserter = mi.get<indexedByName>();
inserter.emplace(0, "uber duber");
inserter.emplace(1, "gotcha");
inserter.emplace(3, "dang");
for(auto& it : mi.get<indexedById>())
std::cout << it.id << ": " << it.name << std::endl;
std::cin.get();
return 0;
}
OK, I fixed it. I needed to include the header files and in addition to the others.
#include <iostream>
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
using namespace boost::multi_index;
struct employee {
employee(unsigned int id, std::string name)
: id(id), name(name)
{}
unsigned int id;
std::string name;
bool operator<(const employee& other) const noexcept {
return this->id < other.id;
}
};
struct indexedById {};
struct indexedByName {};
using EmployeeContainer = boost::multi_index_container
<
employee,
indexed_by<
ordered_unique<tag<indexedById>, identity<employee>>,
hashed_non_unique<tag<indexedByName>, member<employee, std::string, &employee::name>>
>
>;
int main()
{
EmployeeContainer mi;
auto& inserter = mi.get<indexedByName>();
inserter.emplace(0, "uber duber");
inserter.emplace(1, "gotcha");
inserter.emplace(3, "dang");
for(auto& it : mi.get<indexedById>())
std::cout << it.id << ": " << it.name << std::endl;
std::cin.get();
return 0;
}
This is the output:
0: uber duber
1: gotcha
3: dang
So, moral of the story, add header files for each type of index you're doing!
I have a class Project and each Project can have different tasks.
Project.h:
#pragma once
#include "Task.h"
#include <vector>
using namespace std;
class Project
{
private:
vector<Task> Tasks;
public:
Project::Project(int inleesgetal);//constructor
vector<Task> GetTasks();
};
Project.cpp:
#include "Project.h"
#include <string>
#include <vector>
Project::Project(int inleesgetal)
{
//constructor
Tasks.resize(Numbertasks);
}
vector<Task> Project::GetTasks()
{
return Tasks;
}
Task.h:
#pragma once
#include <vector>
using namespace std;
class Task
{
private:
//Info:
int StartTime_Solo;
public:
Task(); //constructor
void SetStartTime_Solo(int st_s);
int GetStartTime_Solo();
};
Task.cpp:
#include "Task.h"
#include <string>
#include <vector>
#include <iostream>
using namespace std;
Task::Task()
{
//constructor
StartTime_Solo = 0;
}
int Task::GetStartTime_Solo()
{
return StartTime_Solo;
}
void Task::SetStartTime_Solo(int st_s)
{
StartTime_Solo = st_s;
}
main:
#include <iostream>
#include <vector>
#include "Task.h"
#include "Project.h"
using namespace std;
int main()
{
Project Project1(6);
Project1.GetTasks()[2].SetStartTime_Solo(55);
cout << "test:" << Project1.GetTasks()[2].GetStartTime_Solo();
return 0;
}
Now when I try to set the 3rd task of Project1 to a starttime of 55 and then print the start time out it still gives me 0 as a result.
Why is this? And how can I change my code so it actually sets the starttime to 55?
vector<Task> GetTasks();
should be
const vector<Task>& GetTasks() const;
vector<Task>& GetTasks();
And so with definitions:
vector<Task> Project::GetTasks()
{
return Tasks;
}
should be:
const vector<Task>& Project::GetTasks() const { return Tasks; }
vector<Task>& Project::GetTasks() { return Tasks; }
The problem is that you are returning a copy of the vector<Task> from the GetTasks function. You then modify this copy and throw it away right afterwards. The internal member of Project is not changed.
If you return by reference like this:
vector<Task>& GetTasks();
Then you are basically returning something that points to the internal vector, and so when you modify it, you actually modify the member data of your class.
I am attempting to make part of a program that uses a bank account class as the base class and checking and savings as the derived classes. I have been trying to set up the basic framework before I do any fancy data handling and I've followed some tutorials to get a better understanding of classes and inheritance.
I have looked for answers but the answers I have found don't seem to be my problem but I might just need another set of eyes on my code.
the compiler errors:
In function main':
badriver.cpp:20: undefined reference toChecking::getAccount()'
badriver.cpp:23: undefined reference to Checking::setAccount(int)'
badriver.cpp:24: undefined reference toSavings::setAccount(int)'
badriver.cpp:26: undefined reference to `Checking::getAccount()'
badriver.cpp
#include "BankAccount.cpp"
#include "Checking.cpp"
#include "Savings.cpp"
#include <string>
#include <iostream>
using namespace std;
int main(){
Checking c;
Savings s;
cout << "Checking: " << c.getAccount() << " - Type: " << c.getType() << endl;
cout << "Savings: " << s.getAccount() << " - Type: " << s.getType() << endl;
c.setAccount(9);
s.setAccount(15);
cout << "New Checking: " << c.getAccount() << endl;
cout << "New Savings: " << s.getAccount() << endl;
return 0;
}
BankAccount.h
#ifndef BANKACCOUNT_H
#define BANKACCOUNT_H
#include <string>
using std::string;
using std::ostream;
using std::istream;
class BankAccount{
private:
int myAccount;
const char* color;
public:
// default constructor
BankAccount();
BankAccount(int account);
virtual ~BankAccount();
virtual void setAccount(int)=0;
int getAccount();
//
// void setSAccount(int);
// int getSAccount();
//
virtual const char* getColor();
virtual const char* getType() = 0;
//virtual const char* getCType() = 0;
protected:
void setColor(const char*);
};
#endif // BANKACCOUNT_H
BankAccount.cpp
#include "BankAccount.h"
#include "Checking.h"
#include "Savings.h"
#include <string>
#include <iostream>
#include <cstdlib>
using namespace std;
// default constructor
BankAccount::BankAccount(){
account = 1;
}
BankAccount::~BankAccount(){}
// void BankAccount::setAccount(int account){
// myAccount = account;
// }
int BankAccount::getAccount(){
return myAccount ;
}
BankAccount::BankAccount(int account){
myAccount = account;
}
const char* BankAccount::getColor(){
return color;
}
void BankAccount::setColor(const char* c){
color = c;
}
Checking.h
#ifndef CHECKING_H
#define CHECKING_H
#include "BankAccount.h"
#include <string>
using std::string;
using std::ostream;
using std::istream;
class Checking : public BankAccount{
private:
const char* type;
public:
Checking();
virtual ~Checking();
void setAccount(int account);
virtual const char* getType();
void setChecking(int);
int getChecking();
};
#endif //CHECKING_H
Checking.cpp
#include "Checking.h"
#include <string>
#include <string>
#include <iostream>
#include <cstdlib>
using namespace std;
Checking::Checking() : BankAccount(1), type("Checking"){}
Checking::~Checking(){}
BankAccount::~BankAccount(){}
void BankAccount::setAccount(int account){
myAccount = account;
}
const char* Checking::getType(){
return type;
}
Savings.h
#ifndef SAVINGS_H
#define SAVINGS_H
#include "BankAccount.h"
#include <string>
using std::string;
using std::ostream;
using std::istream;
class Savings: public BankAccount{
private:
const char* type;
public:
Savings();
virtual ~Savings();
void setAccount(int account);
virtual const char* getType();
void setSavings(int);
int getSavings();
};
#endif // SAVINGS_H
Savings.cpp
#include "Savings.h"
#include <string>
#include <string>
#include <iostream>
#include <cstdlib>
using namespace std;
Savings::Savings() : BankAccount(2), type("Savings"){}
Savings::~Savings(){}
BankAccount::~BankAccount(){}
void BankAccount::setAccount(int account){
myAccount = account;
}
const char* Savings::getType(){
return type;
}
Thanks for any help pointing me in the right direction.
Checking.cpp and Savings.cpp contain:
BankAccount::~BankAccount(){}
void BankAccount::setAccount(int account){
myAccount = account;
}
This causes undefined behaviour because you defined those functions in multiple files. You need to delete those lines from Checking.cpp and Savings.cpp, and instead put in definitions for the functions which are listed as being missing in the compiler output:
void Checking::setAccount(int account){
// code here
}
etc.
hi i was making a program with 3 classes and when i was using a member initialization list i got an error saying "no instance of overloaded function "people::people" matches the specified type:
MAIN.cpp
#include <iostream>
#include "conio.h"
#include <string>
#include "birthday.h"
#include "people.h"
using namespace std;
void main(){
birthday birthObj (30, 06, 1987);
people me("The King",birthObj);
_getch();
}
BIRTHDAY.h
#pragma once
class birthday
{
public:
birthday(int d, int m, int y);
void printdate();
private:
int month;
int day;
int year;
};
BIRTHDAY.cpp
#include "birthday.h"
#include <iostream>
#include "conio.h"
#include <string>
using namespace std;
birthday::birthday(int d, int m, int y)
{
month = m;
day = d;
year = y;
}
void birthday::printdate()
{
cout << day << "/" << month << "/" << year;
}
PEOPLE.h
#pragma once
#include <iostream>
#include "conio.h"
#include <string>
#include "birthday.h"
using namespace std;
class people
{
public:
people(string x, birthday bo);
void printInfo();
private:
string name;
birthday dateOfBirth;
};
PEOPLE.cpp
#include "people.h"
#include <iostream>
#include "conio.h"
#include <string>
#include "birthday.h"
using namespace std;
people::people()
: name(x), dateOfBirth(bo)
{
}
void people::printInfo()
{
cout << name << " was born on ";
dateOfBirth.printdate();
}
People.cpp should be:
people::people(string x, birthday bo) : name(x), dateOfBirth(bo) { }
You havn't implemented the people(string x, birthday bo); constructor. in your PEOPLE.cpp, change
people::people()
: name(x), dateOfBirth(bo)
to
people::people(string x, birthday bo)
: name(x), dateOfBirth(bo)
Your constructor in PEOPLE.cpp has the wrong signature:
It should be:
people::people(string x, birthday bo)
Instead of:
people::people()
people::people()
: name(x), dateOfBirth(bo)
{
}
You have forgotten your arguments to this constructor.
poeple ctor declaration and definition doesn't match!