I recently switched from java to c++ and am not too familiar with the functions of different c++ data structures.
The code below has a queue, Q, of Pets. I am trying to sort the queue by using the struct cmp.
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
enum owner { A, B };
class Pet {
public:
int b, e, id;
owner o;
};
struct cmp
{
bool operator()(Pet a, Pet b) const
{
return a.id - b.id;
}
};
int main(){
queue<Pet, cmp> Q;
}
However, the compiler is giving this error:
no type named 'value_type' in 'cmp'
I have tried debugging, looking at other posts, and changing the (Pet a, Pet b) in cmp to (int a, int b) & etc.
Related
I have made a triplet using a class with all members as integers. I want to insert the triplet in min priority queue using STL in C++. I heard that it can be done using a bool comparator function, but don't have any idea about how to use it with 3 elements.
Note: I don't want to use vector pairs for inserting 3 values (I know how to do it ), I only want to use class triplets.
Can someone help me in implementing it?
using namespace std;
#include<bits/stdc++.h>
class triplet{
public:
int element;
int arrIndex;
int elementIndex;
};
priority_queue<triplet, vector<triplet>, greater<triplet>> pq;
I don`t know why you did std::vector, std::greater but.
#include <queue>
#include <vector>
class triplet {
public:
int element;
int arrIndex;
int elementIndex;
constexpr bool operator>(const triplet& r)
{
return element > r.element;
}
};
int main()
{
std::priority_queue<triplet, std::vector<triplet>, std::greater<>> queue;
triplet a, b;
a.element = 3;
b.element = 5;
queue.push(a);
queue.push(b);
}
This is possible by define a triplet operator.
or
#include <queue>
#include <vector>
class triplet {
public:
int element;
int arrIndex;
int elementIndex;
};
template <>
struct std::greater<triplet>
{
bool operator()(const triplet& l, const triplet& r)
{
return l.element > r.element;
}
};
int main()
{
std::priority_queue<triplet, std::vector<triplet>, std::greater<triplet>> queue;
triplet a, b;
a.element = 3;
b.element = 5;
queue.push(a);
queue.push(b);
}
through template specialization.
The C++ code below keeps giving me a nearly constant output of (0.999976..) as calculated by the Psat() function, whereas, the value is supposed to change meaningfully when I adjust saturation temperature, Tsat???
#include <iostream>
#include <cmath>
using namespace std;
class components{
private:
double A, B, C, Tsat;
public:
void AntParam(double A, double B, double C, double Tsat){
A = A, B = B, C = C, Tsat = Tsat ;}
void Psat(){cout << "Vapor Pressure is "
<<pow(10,(A - B/(C + Tsat)))<<" torr"<<endl;}
};
int main(){
components water;
water.AntParam(8.07131, 1730.63, 233.426, 100);
water.Psat();
return 0; };
The deep, dark secret is Shadowing. The double A parameter is narrower in scope than double A the member variable, so the parameter is the sole owner of the identifier A inside the function. You could this->A = A,..., you could use the member's full name components::A = A, ..., you could rename the parameter, or you could rename the member variable.
Me, I'd use a constructor and make use of the member initializer list.
#include <iostream>
#include <cmath>
using namespace std;
class components
{
private:
double A, B, C, Tsat;
public:
components(double A, double B, double C, double Tsat):
A(A), B(B), C(C), Tsat(Tsat)
{
}
void Psat()
{
cout << "Vapor Pressure is " << pow(10, (A - B / (C + Tsat))) << " torr"
<< endl;
}
};
int main()
{
components water(8.07131, 1730.63, 233.426, 100);
water.Psat();
return 0;
}
Here's the main function ex1-1.cpp
#include <iostream>
#include "ex1-1.h"
using namespace Complex;
int main(int argc, char *argv[])
{
Cplex a={0.0,0.0}, b={0.0,0.0},c={0.0,0.0}, d={0.0,0.0};
// use struct named Cplex under namespace Complex
ReadTextFile(argv[1], a, b);// process text file
std::cout<<a.real<<std::showpos<<a.image<<std::endl;
std::cout<<b.real<<std::showpos<<b.image<<std::endl;
return 0;
}
one header ex1-1.h
#include <iostream>
#include <fstream>
namespace Complex
{
typedef struct
{
double real;
double image;
}Cplex;
Cplex ReadTextFile(char argv[],Cplex a,Cplex b);
}
and one for functions ex1-1-function.cpp
#include<iostream>
#include<fstream>
#include<iomanip>
#include "ex1-1.h"
namespace Complex
{
Cplex ReadTextFile(char argv[],Cplex a,Cplex b)
{
std::ifstream fin;
fin.open("complex.txt");
char i;
fin>>a.real>>a.image>>i;
fin>>b.real>>b.image>>i;
std::cout<<std::noshowpos<<a.real<<std::showpos<<a.image<<"i"<<std::endl;
std::cout<<std::noshowpos<<b.real<<std::showpos<<b.image<<"i"<<std::endl;
return (a,b);
};
}
the text file complex.txt looks like this
1.5+6i
-2-10i
I tried to define a type of structure called Cplex, including two members, real and image
declare Cplex a and Cplex b
then use function ReadTextFileread(argv[1],a,b) to read in two complex numbers and store in the structures a and b
then return a and b at once
But no matter how I tried the main function can only read b instead of both
How can I pass two structures to the main function at once?
Or should I use Array to contain two structures then pass it?
You can use std::pair to couple two values together:
std::pair<Cplex> ReadTextFile(char argv[])
{
Cplex a, b;
...
return { a, b };
};
Then use them like this:
#include <tuple>
...
Cplex a, b;
std::tie(a, b) = ReadTextFile(argv);
Note that std::tie is only available since C++11.
Or if you can use C++17 it will be even simpler to use structured binding:
auto [a, b] = ReadTextFile(argv);
In C & C++ you can return only one value from the function.
Instead use pass by reference to pass the structs 'a' and 'b' and then fill the values within the function.
Declaration:
void ReadTextFile(char argv[],Cplex &a,Cplex &b);
Definition:
void ReadTextFile(char argv[],Cplex& a,Cplex& b)
{
std::ifstream fin;
fin.open("complex.txt");
char i;
fin>>a.real>>a.image>>i; // values filled here can now be read in the caller i.e main.
fin>>b.real>>b.image>>i;
std::cout<<std::noshowpos<<a.real<<std::showpos<<a.image<<"i"<<std::endl;
std::cout<<std::noshowpos<<b.real<<std::showpos<<b.image<<"i"<<std::endl;
return;
};
Hope this helps.
im new in c++ (and not to old in programming...) and i have problem with handling vectors and strucs in class.
basically i have a vector and a array of pointers to struct members in the class and i want work on the in my methos but im doing something worng/
here is my movement.h
#pragma once
using namespace std;
class movement
{
private:
static const int MAX_ROW_PER_TRACKER = 100;
static const int MIN_TO_START_CALC = 30;
static const int MAX_TRACKERS = 20;
struct tracker
{
int id;
double a[MAX_ROW_PER_TRACKER];
double b[MAX_ROW_PER_TRACKER];
double c;
};
vector<int> trackersOrder[MAX_TRACKERS] = {};
tracker* trackersArr[MAX_TRACKERS];
public:
movement();
void addRow(int a, int b, int c);
~movement();
};
and my movement.cpp
#include "stdafx.h"
#include "movement.h"
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
movement::movement()
{
}
void movement::addRow(int id, int a, int b)
{
int index;
vector<int>::iterator searchID = find(trackersOrder.begin(), trackersOrder.end(), ID);
if (searchID == trackersOrder.end())
{
vector<int>::iterator freeLocation = find(trackersOrder.begin(), trackersOrder.end(), 0);
index = freeLocation - trackersOrder.begin();
trackersOrder.insert(trackersOrder.begin + index, id);
structArr[index] = new tracker;
structArr[index]->id = id;
structArr[index]->a[0] = a;
structArr[index]->b[0] = b;
structArr[index]->c = 0;
}
}
movement::~movement()
{
}
so when i send to method "addRow" id, and b i want to first check if i allready have this id in my vector (the vector just give me the index for the structs array) and if not then if put the id in the first empty place in the vector and on the structs array/
but from some reasin its look to me that the methid dont reconized the vector and the structs. can you help me understand why?
p.s - i can bet that i have more mistakes in my code, its my firs try with pointers and ect. (im comming from the good life in Matlab) so i will be happy to learn on them also
thank you very much!
The main problem
The problem is that in your code, trackersOrder is not a vector but an array of vectors:
vector<int> trackersOrder[MAX_TRACKERS] = {}; // array of MAXTRACKERS vectors !!
The solution
If you define it as simple vector, it should work better:
vector<int> trackersOrder;
If you want to set its size do it in the movement constructor:
movement::movement() : trackersOrder(MAX_TRACKERS)
{
}
Other issues
There is a case typo with an ID that should be id.
auto searchID = find(trackersOrder.begin(), trackersOrder.end(), id); // by the way auto is easier + ID corrected
There are a missing () after a begin whicn transforms unfortunately your iterator arithmetic into function pointer arithmetic (sic!!):
trackersOrder.insert(trackersOrder.begin() + index, id); // corrected
Finally, there are a couple of structArr that should be replaced by trackersArr.
The result does finally compile (online demo)
I want to bind a member to store a function object outside of the class instance. Howeber, in VS2012 this only works up to placeholders::_4, then it starts popping up with errors. Take this for example:
#include <iostream>
#include <functional>
using namespace std;
using namespace std::placeholders;
class A
{
public:
int method(int a,int b,int c,int d,int e)
{
return a;
}
};
int main()
{
std::function<int (int,int,int,int,int)> obj;
A a;
// error: no instance of overloaded function "std::bind" matches the argument list
obj = std::bind(&A::method,&a,_1,_2,_3,_4,_5);
std::cout << obj(1,2,3,4,5);
return 0;
}
The above code compiles fine on GCC 4.7.2 but causes the above-mentioned error in Visual Studio 2012. Are there any workarounds, is this a bug in VC++ or am I doing something dodgy here?
Since Visual Studiio does not support variadic templates this is solved by a define.
You can set a define _VARIADIC_MAX to the amount of params you need. Do this in your projects settings to that it is set before any system headers are included.
But keep in mind that setting this value to a large number will increase compile times.
One alternative would be to use a lambda instead like this:
#include <iostream>
#include <functional>
using namespace std;
using namespace std::placeholders;
class A
{
public:
int method(int a, int b, int c, int d, int e)
{
return a;
}
};
int main()
{
std::function<int(int, int, int, int, int)> obj;
A a;
obj = [&a](int b, int c, int d, int e, int f){return a.method(b,c,d,e,f); };
std::cout << obj(1, 2, 3, 4, 5);
return 0;
}
edit: it seems like this won't work either without following #mkaes answer, since apparently the definition of the std::function depends on it.