How can I invoke an overloaded () operator on the keyword this? - c++

The following works but feels ugly when I do the (*this)(5) part.
struct MyStruct
{
void operator()(int a)
{
// Do something with "a"
}
void myFunc()
{
(*this)(5);
}
};
I will need to overload the () operator and use it from within other class methods.

You have a few options:
(*this)(5)
this->operator()(5)
or just operator()(5)
Create a method that you call from within the operator(), e.g.:
void do_work(int a) { /* ... */ }
void operator()(int a) { do_work(a); }
void myFunc() { do_work(5); }
Whichever you choose is just a matter of personal taste.
Just for fun, here are some more (ridiculous) options:
std::invoke (mentioned in comments):
std::invoke(&MyStruct::operator(), this, 5);
mem_fn:
auto call_op = std::mem_fn(&MyStruct::operator());
call_op(this, 5);
lambda:
auto call_op = [this] (int a) { operator()(a); };
call_op(5);
bind_front
auto call_op = std::bind_front(&MyStruct::operator(), this);
call_op(5);

Related

How to access operator[] from inside of a derived class in C++? [duplicate]

The following works but feels ugly when I do the (*this)(5) part.
struct MyStruct
{
void operator()(int a)
{
// Do something with "a"
}
void myFunc()
{
(*this)(5);
}
};
I will need to overload the () operator and use it from within other class methods.
You have a few options:
(*this)(5)
this->operator()(5)
or just operator()(5)
Create a method that you call from within the operator(), e.g.:
void do_work(int a) { /* ... */ }
void operator()(int a) { do_work(a); }
void myFunc() { do_work(5); }
Whichever you choose is just a matter of personal taste.
Just for fun, here are some more (ridiculous) options:
std::invoke (mentioned in comments):
std::invoke(&MyStruct::operator(), this, 5);
mem_fn:
auto call_op = std::mem_fn(&MyStruct::operator());
call_op(this, 5);
lambda:
auto call_op = [this] (int a) { operator()(a); };
call_op(5);
bind_front
auto call_op = std::bind_front(&MyStruct::operator(), this);
call_op(5);

How to Call function pointer from other class

let's say I have simple class with some simple function pointer, like that:
class ClassWithFuncPointer
{
public:
inline void firstFunction() { /* do something */ };
inline void secondFunction() { /* do something */ };
// MY FUNCTION POINTER
void (ClassWithFuncPointer::*funcPointer) ();
// AND I CAN DEFINE IT BY DEFAULT IN CONSTRUCTOR LIKE THAT:
ClassWithFuncPointer()
{
funcPointer = &ClassWithFuncPointer::firstFunction;
}
// AND NOW I CAN USE MY FUNCTION POINTER INSIDE OF ClassWithFuncPointer, LIKE THAT:
void useFunctionPointer()
{
(this->*funcPointer )();
}
}
So here (this->*funcPointer )(); do the job.
But I can't figure it out how to use my funcPointer from other class, I mean something like that:
class otherClass
{
otherClass(){};
ClassWithFuncPointer instanceOfClassWithFuncPointer;
}
And now how can I use funcPointer inside otherClass on member of instanceOfClassWithFuncPointer. Is it possible at all?
I tried many variants:
(this->*instanceOfClassWithFuncPointer.funcPointer)();
or
(instanceOfClassWithFuncPointer.*funcPointer)();
or
( (&instanceOfClassWithFuncPointer)->*funcPointer )();
or just
instanceOfClassWithFuncPointer.funcPointer();
but always get error. I can't figure it out.
What about (C++11 or newer only) as follows?
auto fp = instanceOfClassWithFuncPointer.funcPointer;
(instanceOfClassWithFuncPointer.*fp)();
Or also (C++98 compatible, maybe using shorter variable names) ?
(instanceOfClassWithFuncPointer.*instanceOfClassWithFuncPointer.funcPointer)();
The following is a full working example
#include <iostream>
struct ClassWithFuncPointer
{
public:
inline void firstFunction ()
{ std::cout << "cwfp::firstFunction()" << std::endl; }
inline void secondFunction ()
{ std::cout << "cwfp::secondFunction()" << std::endl; }
void (ClassWithFuncPointer::*funcPointer) ();
ClassWithFuncPointer()
{ funcPointer = &ClassWithFuncPointer::firstFunction; }
void useFunctionPointer()
{ (this->*funcPointer )(); }
};
class otherClass
{
public:
otherClass ()
{ }
ClassWithFuncPointer instanceOfClassWithFuncPointer;
void foo ()
{
auto fp = instanceOfClassWithFuncPointer.funcPointer;
(instanceOfClassWithFuncPointer.*fp)();
}
};
int main ()
{
otherClass oc;
oc.foo();
}

How to make a Poco::Delegate from a lambda function?

I have a code like this:
void func1(const void *oo, int &a)
{
...
}
void test()
{
auto del1 = Poco::delegate(func1);
}
and it works fine, but when i wanna use a lambda function instead of func1 like this code:
void test()
{
auto func2 = [](const void *oo, int &a)
{
...
};
auto del1 = Poco::delegate(func2);
}
it doesn't work, and give some errors like
no matching function for call to 'delegate(test()::<lambda(const void*,
const int&)>&)'
How can i make a Poco::Delegate from a lambda, or (more accurate) from result of std::bind?
Any help would be greatly appreciated, thanks.

Using auto specifier in std::function and lambdas

I have a class named Handler wich stores some lambdas. What I want to do is to have a std::vector of std::function that stores all my events, for exemple. I really can't figure out why lambdas doesn't work as I expected.
Here's the handler.h:
class Handler
{
public:
Handler();
~Handler();
void Register(const char* outcome, std::function<auto()> lambda);
void Trigger(const char* outcome);
private:
std::vector<int> identifier;
std::vector<char*> outcome;
std::vector<std::function<auto()>> func;
};
And handler.cpp:
Handler::Handler()
{
//ctor stuff here
}
Handler::~Handler()
{
this->func.clear();
this->outcome.clear();
this->identifier.clear();
//...
}
void Handler::Register(const char* outcome, std::function<auto()> lambda)
{
static int identifier = 0;
identifier++;
this->outcome.push_back((char*)outcome);
this->identifier.push_back(identifier);
this->func.push_back(lambda);
//Sort outcome
}
void Handler::Trigger(const char * outcome)
{
int i;
for (i = 0; i < this->identifier.size(); i++)
{
if (!strcmp(outcome, this->outcome.at(i)))
break;
}
this->func[i]();
}
However, if I specify lambdas in a Handler::Register it wont let me throwing no suitable user-defined conversion from "lambda []void ()->void" to "std::function<auto()> exists. In this example I use void return type but other types also error, I don't understant why can't the template from std::function deduce it out, if it is what's happening.
Handler* events = new Handler();
events->Register("Up", [=]() -> void { //Error here!
//do stuff
//return something?
});
Is there any other way to do this, like without overloading Handler::Register?
auto is not a type, so std::function<auto()> is not a type either. From how you are using it, std::function<void()> is probably what you want.
There are other problems with your code, as noted in the comments, so I would change Handler to this
class Handler
{
public:
Handler();
// default ~Handler is fine
void Register(std::string outcome, std::function<void()> lambda);
void Trigger(const std::string & outcome outcome) const;
void Trigger(std::size_t index) const;
private:
using Outcomes = std::map<std::string, std::function<void()>/*, custom string comparator ?*/>;
std::vector<Outcomes::iterator> identifier;
Outcomes outcomes;
};
void Handler::Register(std::string outcome, std::function<void()> func)
{
auto emplaced = outcomes.emplace(std::move(outcome), std::move(func));
identifier.push_back(emplaced.first);
}
void Handler::Trigger(const std::string & outcome) const
{
outcomes.at(outcome)();
}
void Handler::Trigger(std::size_t index) const
{
identifier[index]->second();
}

C++ type erasure, capture multiple methods of a single class with std::function

Consider the following code, in which std::function is used three times to capture the methods of one class:
struct some_expensive_to_copy_class
{
void foo1(int) const { std::cout<<"foo1"<<std::endl; }
void foo2(int) const { std::cout<<"foo2"<<std::endl; }
void foo3(int) const { std::cout<<"foo3"<<std::endl; }
};
struct my_class
{
template<typename C>
auto getFunctions(C const& c)
{
f1 = [c](int i) { return c.foo1(i);};
f2 = [c](int i) { return c.foo2(i);};
f3 = [c](int i) { return c.foo3(i);};
}
std::function<void(int)> f1;
std::function<void(int)> f2;
std::function<void(int)> f3;
};
This, however, will perform three copies of the class some_expensive_to_copy_class, which is inefficient as one could have guessed by the name.
Is there a workaround such that only one copy is made?
To emphasize it, I'm interested here in the approach using std::function, not void-pointers and also not the corresponding inheritance-based implementation.
Make a copy with a shared_ptr, and capture that.
auto spc = std::make_shared<const C>(c);
f1 = [spc](int i) { return spc->foo1(i); }
f2 = [spc](int i) { return spc->foo2(i); }
f3 = [spc](int i) { return spc->foo3(i); }