Error: expression cannot be used as an function - c++

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.

Related

How to remove an element from a vector using remove_if

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.

Class operators

I'm having a problem to make the code:
void main(){
Matrix c(rows,cols);//rows & cols are int numbers
c[0][0]=2//the line that I'm having a problem to do the operator
}
//My class defined like this:
class Matrix{
public:
Matrix(int rows,int cols): rows(rows), cols(cols){
mat= new double*[cols];
for( int i=0; i<rows;i++){
*mat=new double[i];
}
}
private:
int rows,cols;
double **mat;
};
How can I make an operator that will help me to do the line that I'm having a problem with?
There are no operator [][], but operator[]. So that one should return something for which you can use [] too (pointer or proxy class).
In your case, you might simply do:
double* operator[](int i) { return mat[i]; }
const double* operator[](int i) const { return mat[i]; }
For more complicated cases, you have to return a proxy class.
Don't dynamically allocate in two dimensions like that. It's poison for your cache, and completely pointless. I see it all the time and I wish I didn't! Make yourself a nice std::vector<double> of size rows*cols instead.
Anyway, the trick to permit [width][height] is a proxy class. Have your operator[] return an instance of a class that has its own operator[] to do the second-level lookup.
Something like this:
#include <iostream>
#include <vector>
struct Matrix
{
Matrix(const size_t columns, const size_t rows)
: columns(columns)
, rows(rows)
, data(columns*rows, 0)
{}
size_t index(const size_t x, const size_t y) const
{
return x + y*columns;
}
double& at(const size_t x, const size_t y)
{
return data[index(x, y)];
}
double at(const size_t x, const size_t y) const
{
return data[index(x, y)];
}
template <bool Const>
struct LookupHelper
{
using ParentType = std::conditional_t<Const, const Matrix, Matrix>;
using ReturnType = std::conditional_t<Const, double, double&>;
LookupHelper(ParentType& parent, const size_t x) : parent(parent), x(x) {}
ReturnType operator[](const size_t y)
{
return parent.data[parent.index(x, y)];
}
const ReturnType operator[](const size_t y) const
{
return parent.data[parent.index(x, y)];
}
private:
ParentType& parent;
const size_t x;
};
LookupHelper<false> operator[](const size_t x)
{
return {*this, x};
}
LookupHelper<true> operator[](const size_t x) const
{
return {*this, x};
}
private:
const size_t columns, rows;
std::vector<double> data;
};
int main()
{
Matrix m(42, 3);
m[15][3] = 1;
std::cout << m[15][3] << '\n';
}
(In reality, you'd want to make it moveable and it could doubtlessly be tidied up a bit.)
Certainly, switching to operator() or a .at(width, height) member function is a lot easier…

C++ Pass member function pointer to inner-class

Implementing operator[][] using proxy class. Works fine for single 2-dimensional data structure which can be accessed by some double data(int row, in col) method. However if I want to have few data methods I'd like to use pointer to member function which is stored in proxy inner-class TPatternRow:
class TLearnPattern
{
public:
typedef int (TLearnPattern::* IndexFunction)(int);
typedef double (TLearnPattern::* DataFunction)(int, int);
TLearnPattern(TDataSource *source);
class TPatternRow ///< Proxy class to implement operator[][]
{
public:
TPatternRow(TLearnPattern& source, int row, DataFunction func) :
lp(source),
i(row),
data(func)
{}
double& operator[](int j) { return (lp.*data)(i, j); }
private:
TLearnPattern& lp;
DataFunction data = &TLearnPattern::in;
int i;
};
TPatternRow operator [](int i) { return TPatternRow(*this, i, &TLearnPattern::in); }
TPatternRow In(int i) { return TPatternRow(*this, i, &TLearnPattern::in); }
TPatternRow Out(int i) { return TPatternRow(*this, i, &TLearnPattern::out); }
virtual double in(int row, int col) final;
virtual double out(int row, int col) final;
}
How to syntactically correctly call following line?
double& operator[](int j) { return (lp.*data)(i, j); }
Use std::bind? How to correctly bind this in TPatternRow constructor?
And some related question: does bind works fast enough comparing to just pointer to member function call?
Solved like this:
double operator[](int j)
{
auto dataFunc = std::bind(data, lp, _1, _2);
return dataFunc(i, j);
}
or original without &:
double operator[](int j) { return (lp.*data)(i, j); }

How to make a class's function default

Example code:
class Sum{
public:
void value(int val){_v = val;}
int add(int val){return _v + val;}
private:
int _v;
};
Sum sum;
sum.value(5);
int myResult = sum.add(10);
Is it possible to make the sum.add(10) default so I can get the same result like this:
int myArea = sum(10);
(I suspect the question title is wrong, perhaps it is the reason why I can't find a solution. Feel free to edit.)
Yes you can. What you can do is overload the operator() of the class to turn it into a functor. You can add
int operator()(int val) { return add(val); }
To the class and now sum(some_value) is the same thing as sum.add(some_value)
That's specifically what the function call operator is for.
class Sum{
public:
void value(int val){ _v = val; }
int add(int val) const{ return _v + val; }
// Function call operator
int operator()(int val) const {
return add(val);
}
private:
int _v;
};
int main()
{
Sum sum;
sum.value(5);
// Calls the function call operator
int myResult = sum(10);
}

Multiple Type output in Polymorphism

I have a problem when i want to create a pure virtual function and assign to this multiple range of output formats (like int, double and char).
i wrote below code and it works only when i eliminate my abstract class which it's not thing that i want.
my code:
enter code here
//class DynamicArray
//{
// public:
// virtual void GetData(unsigned int s, int& d) = 0;
// virtual void SetData(unsigned int s, int& d) = 0;
//};
class DynamicArrayDouble//: public DynamicArray
{
private:
unsigned int m_Length;
double* arr;
public:
DynamicArrayDouble(unsigned int l)
{
m_Length = l;
arr = new double[m_Length];
}
void SetParam(unsigned int l)
{
m_Length = l;
arr = new double[m_Length];
}
void GetData(unsigned int s, double& d)
{
d = arr[s];
}
void SetData(unsigned int s, double& d)
{
arr[s] = d;
}
};
when i uncomment DynamicArray class and DynamicArrayDouble inherit it i face with some error. it should be noted, first time i try to use void* for second parameter for Set and Get methods, but again i receive some errors that i can't use this code style like this:
error: cannot declare variable 'd1' to be of abstract type 'DynamicArrayDouble'
and code of above error is:
class DynamicArray
{
public:
virtual void GetData(unsigned int s, void* d) = 0;
virtual void SetData(unsigned int s, void* d) = 0;
};
class DynamicArrayDouble: public DynamicArray
{
private:
unsigned int m_Length;
double* arr;
public:
DynamicArrayDouble(unsigned int l)
{
m_Length = l;
arr = new double[m_Length];
}
void SetParam(unsigned int l)
{
m_Length = l;
arr = new double[m_Length];
}
void GetData(unsigned int s, double* d)
{
*d = arr[s];
}
void SetData(unsigned int s, double* d)
{
arr[s] = *d;
}
};
int main()
{
DynamicArrayDouble d1(5);
double x=0;
for(unsigned int i=0;i<5;i++)
{
x = ((i+1.0)/2);
d1.SetData(i,&x);
}
for(unsigned int i=0;i<5;i++)
{
d1.GetData(i,&x);
cout << "Data " << i+1 << " is = " << x << endl;
}
return 0;
}
i write my codes in codeblocks.
i will appreciate your answer... Thank you.
You can't simply override
void func(some_pointer_type ptr);
with
void func(some_other_pointer_type ptr);
and same goes for references. Those are in fact considered to be completely unrelated if they don't match.
DynamicArrayDouble - this name tells me you should look into templates and not write the same code for all the types you'll need. This is how STL works. You'll completely avoid runtime polymorphism.
For starters:
template <typename T>
DynamicArray;