the differences between function-object and function-pointer? - c++

i defined a class, then save the pointer to Foo in the priority_queue, and use the cmp-function that i defined.
but if the cmp-funtion calls the function-object, an error occurs:
class Foo
{
friend bool cmp(Foo *, Foo *);
public:
Foo() = default;
Foo(int x):val(x) {}
private:
int val;
};
bool cmp(Foo *a, Foo *b)
{
return a->val < b->val;
}
int main()
{
priority_queue<Foo*, vector<Foo*>, decltype(cmp)*> que;
que.push(new Foo(5));
que.push(new Foo(6));
return 0;
}
the functione-object runs normally.
class Foo
{
friend struct cmp;
public:
Foo() = default;
Foo(int x):val(x) {}
private:
int val;
};
struct cmp
{
bool operator()(Foo *a, Foo *b)
{
return a->val < b->val;
}
};
int main()
{
priority_queue<Foo*, vector<Foo*>, cmp> que;
que.push(new Foo(5));
que.push(new Foo(6));
return 0;
}

You need to construct your que variable with the function you wish to use as a comparison.
#include <vector>
#include <queue>
using namespace std;
class Foo
{
friend bool cmp(Foo*, Foo*);
public:
Foo() = default;
Foo(int x):val(x) {}
private:
int val;
};
bool cmp(Foo* a, Foo* b)
{
return a->val < b->val;
}
int main()
{
// vvv
priority_queue<Foo*, vector<Foo*>, decltype(cmp)*> que(cmp);
que.push(new Foo(5));
que.push(new Foo(6));
return 0;
}

Related

C++ Similar functions using different data types

I have two functions which are exactly the same, except that one of them uses a stack for its operations and the other one uses a queue:
void doQueue()
{
std::queue<int> q;
...
...
q.push(someValue);
...
...
int tmp = q.front();
q.pop()
}
void doStack()
{
std::stack<int> s;
...
...
s.push(someValue);
...
...
int tmp = s.top();
s.pop()
}
I want to eliminate duplicate code. As queue uses the front function to retrieve the first value and stack uses the top function, I thought that templates may not work since functions with different names have to be called.
My other idea was to create an interface which will be as a wrapper to both data structures and I can pass around the one that I need.:
class Data
{
public:
virtual void push(const int v) = 0;
virtual int pop() = 0;
};
class StackData : public Data
{
private:
std::stack<int> _stack;
public:
virtual void push(const int v) {_stack.push(v);}
virtual int pop()
{
int ret = _stack.top();
_stack.pop();
return ret;
}
};
class QueueData : public Data
{
private:
std::queue<int> _queue;
public:
virtual void push(const int v) {_queue.push(v);}
virtual int pop()
{
int ret = _queue.front();
_queue.pop();
return ret;
}
};
void doData(Data& dataType)
{
...
dataType.push(someValue);
...
int tmp = dataType.pop();
}
void doQueue()
{
QueueData queueData;
doData(queueData);
}
void doStack()
{
StackData stackData;
doData(stackData);
}
But I think there should be an easier and better way to perform this operation.
Here's one way - a wrapper template with partial specialisation on underlying container type:
#include <stack>
#include <queue>
template<class Container>
struct generic_sequence_ops;
template<class T, class UnderlyingContainer>
struct generic_sequence_ops<std::stack<T, UnderlyingContainer>>
{
using container_type = std::stack<T, UnderlyingContainer>;
using value_type = typename container_type::value_type;
generic_sequence_ops(container_type& c) : c(c) {}
void add_one(value_type v)
{
c.push(std::move(v));
}
void remove_one()
{
c.pop();
}
value_type& current()
{
return c.top();
}
container_type& c;
};
template<class T, class UnderlyingContainer>
struct generic_sequence_ops<std::queue<T, UnderlyingContainer>>
{
using container_type = std::queue<T, UnderlyingContainer>;
using value_type = typename container_type::value_type;
generic_sequence_ops(container_type& c) : c(c) {}
void add_one(value_type v)
{
c.push(std::move(v));
}
void remove_one()
{
c.pop();
}
value_type& current()
{
return c.back();
}
container_type& c;
};
template<class Container>
auto make_generic_sequence_ops(Container& cont)
{
return generic_sequence_ops<std::decay_t<Container>>(cont);
}
template<class Container>
int doContainer(Container& cont)
{
auto s = make_generic_sequence_ops(cont);
s.add_one(6);
int val = s.current();
s.remove_one();
return val;
}
int main()
{
std::queue<int> q;
std::stack<int> s;
doContainer(q);
doContainer(s);
}

c++ unordered_set Comparator function for a user-defined class

I have something like this:
using namespace std;
class QuadraticPrimeSolution
{
private:
int a;
int b;
int numberOfPrimes;
bool isPrime(int n, set<int> &primeHash);
public:
QuadraticPrimeSolution(int a, int b):a(a),b(b),numberOfPrimes(0){};
void calculateNumberOfPrimes(set<int> &primeHash);
int getNumberOfPrimes(){return numberOfPrimes;}
};
class QuadraticPrimeSolver
{
private:
struct classcomp {
bool operator() (QuadraticPrimeSolution& lhs, QuadraticPrimeSolution& rhs)
{
return lhs.getNumberOfPrimes()>rhs.getNumberOfPrimes();
}
};
set<QuadraticPrimeSolution, classcomp> solutions;
set<int> primeHash;
QuadraticPrimeSolution getMaxSolution();
int a;
int b;
public:
QuadraticPrimeSolver(int a, int b):a(a), b(b){};
void solve();
};
bool QuadraticPrimeSolution::isPrime(int n, set<int> &primeHash)
{
if(primeHash.empty())
{
primeHash.insert(n);
return true;
}
for(auto it= primeHash.begin(); it!= primeHash.end(); it++)
{
if(n%(*it)==0)
{
return false;
}
}
primeHash.insert(n);
return true;
}
void QuadraticPrimeSolver::solve()
{
for(int i=(-1)*a; i<=a; i++)
{
for(int j=(-1)*b; j<=b; j++)
{
QuadraticPrimeSolution aSolution = new aSolution(i,j);
aSolution.calculateNumberOfPrimes(primeHash);
solutions.insert(aSolution);
}
}
}
int main()
{
QuadraticPrimeSolver QPS(0,40);
QPS.solve();
}
Basically what I am trying to do is compute and store each QuadraticPrimeSolution into a hash table in QuadraticPrimeSolver which I can then access later.
My question is, is my comparator implementation correct? Right now compiler is complaining about my comparator, and the following line for inserting into a set.
solutions.insert(aSolution);
Please help!
class building
{
public:
int getPosition() const {return position;};
private:
int height;
int position;
};
class ManyBuildings
{
public:
void populateBuildings(std::vector<std::string> buildings);
private:
class comparePosition {
public:
bool operator () (const building &lhs, const building &rhs) {
return lhs.getPosition() > rhs.getPosition();
}
};
std::set<building, comparePosition> buildings;
};
use set instead of unordered_set
template parameter for set should be a type, not a function

C++ no matching function for call

I have error: No matching function for call to 'Goo::Goo()'
This problem is happening to often, can somebady explain to me where do i make mistakes all the time. I How can i overcome this.
Here is the code of the progam:
#include <iostream>
using namespace std;
class Goo{
private:
int a[10];
int n;
public:
Goo(int x){
n=x;
}
Goo(const Goo &g){
this->n=g.n;
for(int i=0;i<g.n;i++){
this->a[i]=g.n;
}
}
Goo operator=(const Goo &g){
this->n=g.n;
for(int i=0;i<g.n;i++){
this->a[i]=g.n;
}
return *this;
}
Goo operator+(const Goo &g){
Goo goo;
for(int i=0;i<g.n;i++){
goo.a[i]=this->a[i]+g.a[i];
}
return goo;
}
friend istream& operator>>(istream &in,Goo &g){
in>>g.n;
for(int i=0;i<g.n;i++){
in>>g.a[i];
}
return in;
}
friend ostream& operator<<(ostream &out,Goo &g){
for(int i=0;i<g.n;i++){
out<<g.a[i]<<" ";
}
return out;
}
};
int main()
{
Goo A,B;
cin>>A>>B;
Goo C=A+B;
cout<<C;
return 0;
}
When you define a custom constructor (among other reasons), the class no longer has a default constructor:
struct Foo {
int x;
};
Foo foo; // OK
struct Foo {
int x;
Foo(int x_) : x{x_} { }
};
Foo foo; // error
You can fix this by either adding a custom default constructor:
struct Foo {
int x;
Foo() { }
Foo(int x_) : x{x_} { }
};
or having at least one constructor with all default parameters:
struct Foo {
int x;
Foo(int x_ = 0) : x{x_} { }
};
Since C++11, you can also force the compiler to emit the default constructor:
struct Foo {
int x;
Foo() = default;
Foo(int x_ = 0) : x{x_} { }
};

Defining a function template as a callback for a class template

I want to define a class template that takes a callback function of the same type. Something like:
typedef template<class T> bool CallbackFn( T x );
template<class T> class MyClass
{
public:
MyClass() {}
~MyClass() {}
void addCallbackFn( CallbackFn* fn ) { callbackFn = fn; }
private:
CallbackFn* callbackFn;
};
And it would be used like this:
bool testFunctionInt(int x) { return true; }
bool testFunctionString(std::string x) { return true; }
MyClass<int> a;
a.addCallbackFn( testFunctionInt );
MyClass<std::string> b;
b.addCallbackFn( testFunctionString );
Unfortunately the callback function cannot be defined as a function template via the typedef.
Is there another way to do this?
#include <string>
template <typename T>
class MyClass {
public:
typedef bool CallbackFn(T x);
MyClass() : cb_(NULL) {}
~MyClass() {}
void addCallbackFn(CallbackFn *fn) { cb_ = fn; }
private:
CallbackFn *cb_;
};
static bool testFunctionInt(int x) { return true; }
static bool testFunctionString(std::string x) { return true; }
int main()
{
MyClass<int> a;
a.addCallbackFn( testFunctionInt );
MyClass<std::string> b;
b.addCallbackFn( testFunctionString );
}
Move the typedef inside of the class like this:
template<class T> class MyClass
{
public:
MyClass() {}
~MyClass() {}
typedef bool CallbackFn( typename T x );
void addCallbackFn( CallbackFn* fn ) { callbackFn = fn; }
//you could also do this
typedef bool (*CallbackFnPtr)(typename T x);
void addCallbackFnPtr(CallbackFnPtr fn ) { callbackFn = fn; }
private:
CallbackFn* callbackFn; //or CallbackFnPtr callbackFn;
};
I'm assuming you meant MyClass<std::string> b; in your example.
I made some changes.
template<class T>
class MyClass
{
public:
typedef bool (*CallbackFn)( T x );
MyClass() {}
~MyClass() {}
void addCallbackFn( CallbackFn fn ) { callbackFn = fn; }
private:
CallbackFn callbackFn;
};
bool testFunctionInt(int x)
{
return true;
}
int main(int argc, char * argv[])
{
MyClass<int> c;
c.addCallbackFn(testFunctionInt);
return 0;
}

Is there a way to forbid casting to subclass that is non-const in C++?

Here is a complete example.
I want to forbid using A::set from objects casted from B to A by allowing only casting
B to const A.
How to do it?
(I can't use virtual functions)
#include <iostream>
#include <cassert>
using namespace std;
class A {
public:
int get() const { return i_; }
void set(int i) { i_ = i; }
protected:
int i_;
};
class B : public A {
public:
int ok() const { return A::get() == copy_i_; }
void set(int i) { A::set(i); copy_i_ = i; }
protected:
int copy_i_;
};
void test2() {
A a;
a.set(3); // ok here
cout << a.get() << endl;
B b;
b.set(5);
A& aa = b;
assert(b.ok());
aa.set(3); // not ok here
assert(b.ok()); // fail-here
}
int main() {
test2();
return 0;
}
You could make the inheritance private and provide a member function in B to use instead of casting.
const A& B::convert_to_A() const { return *this; }
Why casting? Making void A::set(int i) protected will work in your case.
There is no need for forbidding non-const casts. You can solve your problem by using the template method design pattern.
#include "stdafx.h"
#include <iostream>
#include <cassert>
using namespace std;
class A {
public:
int get() const { return i_; }
void set(int i) { assert(i_ = i); copy_i();}
protected:
int i_;
virtual void copy_i(){};
};
class B : public A {
public:
int ok() const { return A::get() == copy_i_; }
protected:
int copy_i_;
void copy_i(){copy_i_ = i_; }
};
void test2() {
B b;
b.set(5);
A& a = b;
assert(b.ok());
a.set(3);
assert(b.ok()); // success!
}
int main() {
test2();
return 0;
}