I have the below code: I face compilation error in remove function. I want to remove the elements from the vector whose elements have an x match the value of input x.
class A
{
int x,y;
public:
init(int a, int b)
{
x = a; y= b;
}
int getX(){return x;}
}
class B
{
public:
void add (int a, int b)
{
A a1;
a1.init(a,b);
MyVector.push_back(a1);
}
void remove(int x)
{
MyVector.erase(remove_if(MyVector.begin(), MyVector.end(),
[&vec](int x){return (vec.getX() == x);}), MyVector.end());
}
vector<A> MyVector;
}
You must give a return type to init(int a, int b) and you've missed two ;s after the classes definitions and used std::remove_if() incorrectly. here is its documentation
#include <vector>
#include <algorithm>
class A
{
int x,y;
public:
void init(int a, int b)
{
x = a; y= b;
}
int getX(){return x;}
};
class B
{
public:
void add (int a, int b)
{
A a1;
a1.init(a,b);
MyVector.push_back(a1);
}
void remove(int x)
{
MyVector.erase(std::remove_if(MyVector.begin(), MyVector.end(),
[&x](auto & el){return (el.getX() == x);}), MyVector.end());
}
std::vector<A> MyVector;
};
Note that auto & el == A & el. std::remove_if iterates over the vector and passes its elements to the lambda, hence the lambda argument type should be as the vector's one.
Related
Suppose I have some functions which have the same parameters and datatype, and I want to push them into a std::vector and enumerate them.
Is it possible to do this?
Pseudocode:
typedef int func(int, int);
int add(int a, int b)
{
return a + b;
}
int minus(int a, int b)
{
return a - b;
}
vector<func> operations = {add, minus};
for (auto operation : operations)
{
// do something
}
What you are missing in your code is a * in std::vector<func> because you want to store pointers to the function:
#include <vector>
#include <functional>
#include <iostream>
typedef int func(int, int);
int add(int a, int b)
{
return a + b;
}
int minus(int a, int b)
{
return a - b;
}
int main() {
std::vector<func*> operations = {add, minus};
for (auto operation : operations)
{
}
}
You could also use std::function for that purpose:
#include <vector>
#include <functional>
int add(int a, int b)
{
return a + b;
}
int minus(int a, int b)
{
return a - b;
}
int main() {
std::vector<std::function<int(int,int)>> operations = {add, minus};
for (auto operation : operations)
{
// do something
}
}
Related question:
How can I store function pointer in vector?
I'm trying to populate a vector of type pointer to class B, which I'll be using later.
When I try to read the vector's element, the value I'm getting is different from what I've given.
Can someone please help me here, what mistake I'm making and how to correct it?
Thanks
#include <iostream>
#include <vector>
class B {
public:
int b;
B (int n) {
b = n;
}
};
std::vector<B*> v;
class A {
public:
int a;
void func(int n);
};
void A::func(int n) {
B obj_b(n);
B* ptr = &obj_b;
v.push_back(ptr);
}
int main() {
A obj_a;
obj_a.a = 5;
obj_a.func(4);
std::cout<<obj_a.a<<std::endl;
for (auto it:v) {
std::cout<<it->b<<std::endl;
}
}
The output I'm getting is:
5,
32765
Whereas the expected output is:
5,
4
Using value instead of pointer, as per the comments above:
#include <iostream>
#include <vector>
class B {
public:
int b;
B (int n) {
b = n;
}
};
std::vector<B> v;
class A {
public:
int a;
void func(int n);
};
void A::func(int n) {
v.emplace_back(n);
}
int main() {
A obj_a;
obj_a.a = 5;
obj_a.func(4);
std::cout<<obj_a.a<<std::endl;
for (auto& e:v) {
std::cout<<e.b<<std::endl;
}
}
You can use heap allocations and take advantage of std::unique_ptr<T>. Here is the fix:
#include <iostream>
#include <vector>
#include <memory>
class B
{
public:
B ( const int n )
{
b = n;
}
int b;
};
std::vector< std::unique_ptr<B> > v; // use a vector of B pointers
// ( std::unique_ptr<B> )
class A
{
public:
void func( const int n );
int a;
};
void A::func( const int n )
{
v.push_back( std::make_unique<B>( n ) ); // returns a pointer object of type
} // std::unique_ptr<B>
int main ()
{
A obj_a;
obj_a.a = 5;
obj_a.func( 4 );
std::cout << obj_a.a << std::endl;
for ( const auto& ptrB : v )
{
std::cout << ptrB->b << std::endl; // use -> operator to have access to
} // ptrB's members
return 0;
}
Hopefully, this helps.
I have a class which has a member attribute consisting of an object defined elsewhere. In the code below, A contains a public attribute var which is a B:
class B {
public:
int x, y;
std::vector<int> z;
B(int a, int b, std::vector<int> c) {
x = a; y = b; z = c;
}
};
class A {
public:
B var;
A(int i, int j) {
std::vector<int> someVector;
B(i, j, someVector);
}
};
int main() {
A foo(5, 3);
return 0;
}
This (obviously) doesn't compile as var is instantiated upon an instantiation of A, too late for it to be constructed.
The best way I can do something similar is modify some code:
class B {
public:
int x, y;
std::vector<int> z;
B() {}
void setAttributes(int a, int b, std::vector<int> c) {
x = a; y = b; z = c;
}
};
class A {
public:
B var;
A(int i, int j) {
std::vector<int> someVector;
B.setAttributes(i, j, someVector);
}
};
This does compile because attributes are set after instantiation.
But is there a way to remain closer to the first code snippet?
A(int i, int j) : var(i, j, {}) {}
Also, in your code B(i, j, someVector); does not initialize member variable var, and B.setAttributes(i, j, someVector); wouldn't compile at all.
if you cannot define a useful default constructor and don't want the ugly two step initialization, I guess there is no way around a pointer to B. Something like
#include <memory>
class B {
public:
int x, y;
std::vector<int> z;
B(int a, int b, std::vector<int> c) {
x = a; y = b; z = c;
}
};
class A {
public:
std::unique_ptr<B> var;
A() {
std::vector<int> someVector;
var = std::make_unique<B>(5, 2, someVector);
}
};
int main() {
A foo();
return 0;
}
should do the trick.
I'm new to lambdas, I made my own binary heap class with custom comparator function.
It went well until I got a compilation error and I don't know how to fix.
I tried to change my line of code a bit, instead of
this(capacity, [](int a, int b){return a - b;});
I changed to this:
function<int(int, int)> cmp = [](int a, int b){return a - b;};
this(capacity, cmp);
I got the same result. How to deal with this error?
binary heap class:
class binaryheap
{
private:
int *heap;
int size;
int capacity;
function<int(int, int)> cmp;
int parent(int i);
int left_child(int i);
int right_child(int i);
void swap(int *a, int *b);
void heapify(int i);
public:
binaryheap(int capacity);
binaryheap(int capacity, const function<int(int, int)>& cmp);
~binaryheap();
bool empty();
int heap_size() const;
int get_root() const;
int extract_root();
void decrease_key(int i, int value);
void insert_key(int key);
void delete_key(int i);
};
The part of my code with a compilation error
binaryheap::binaryheap(int capacity)
{
this(capacity, [](int a, int b){return a - b;});//binaryheap.cpp:51:58: error: expression cannot be used as a function
}
binaryheap::binaryheap(int capacity, const function<int(int, int)>& cmp)
{
this->capacity = capacity;
this->heap = new int[capacity + 1];
this->size = 0;
this->cmp = cmp;
}
I suppose you want to use the delegating constructor feature; so
binaryheap::binaryheap (int capacity)
: binaryheap{capacity, [](int a, int b){return a - b;}}
{ }
or, as suggested by melpomene (thanks), you can delete this constructor and add a default value ([](int a, int b){return a - b;}) for the second argument in the other constructor.
I would like to know how to remove an object from a list base on a condition.
After researching, this is what I got, but it still doesn't work!
So I would like to know how to use remove_if with erase.
Class A
{
public:
A(int x,int y);
int x;
int y;
};
int main()
{
list<A> listA;
A lista1(123,32);
listA.push_back(lista1);
A lista2(3123,1233);
listA.push_back(lista2);
A lista3(123,4123);
listA.push_back(lista3);
//HERE HOW TO REMOVE LIST if x = 123?
listA.erase(remove_if(listA.begin(),listA.end(),/*REMOVE CRITERIA*/);
}
std::list has a remove_if member function:
http://www.cplusplus.com/reference/stl/list/remove_if/
For your predicate you could either write a functor:
struct RemoveIfX
{
RemoveIfX(int x) : m_x(x) {}
bool operator() (const A& a)
{
return (a.x == m_x);
}
int m_x;
};
listA.remove_if(RemoveIfX(123));
Or use a lambda:
listA.remove_if([](const A& a) { return (a.x == 123); });