How to access operator[] from inside of a derived class in C++? [duplicate] - 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 can I invoke an overloaded () operator on the keyword this?

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();
}

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); }

What is the syntax for storing a specific class's member functions in a vector?

I did quite a bit of searching, but the combination of * () and class scope has greatly hindered me in understanding of the syntax, with each edit throwing a new error, any help guys?
What I'm trying to do:
Declare a std::vector of pointers to member functions found in MyClass.h
Assign the actual member functions to the std::vector in MyClass.cpp's constructor
The member functions are not static
Thanks!
I'm curious where you're going to use them from. You see in order to call a C++ class member function you need to have an instance pointer with which to call it (each member function needs a this in order to access the class state). So normally you'd wrap the member function pointer together with the instance pointer with std::bind and then maybe store the result in std::function. To put them in vector they're all going to need the same signature.
Is this the kind of thing you were looking for:
class P
{
typedef std::function<void (void)> func_t;
std::vector<func_t> functions;
public:
P()
{
functions.push_back(std::bind(&P::foo1, this));
functions.push_back(std::bind(&P::foo2, this));
functions.push_back(std::bind(&P::foo3, this));
}
void foo1(void)
{
std::cout << "foo1\n";
}
void foo2(void)
{
std::cout << "foo2\n";
}
void foo3(void)
{
std::cout << "foo3\n";
}
void call()
{
for(auto it = functions.begin(); it != functions.end(); ++it)
{
(*it)();
}
}
};
int main()
{
P p;
p.call();
}
After further clarification from the OP I'll propose this:
class P
{
typedef std::function<void (void)> func_t;
std::map<const char*, func_t> functions;
public:
P()
{
functions["foo1"] = std::bind(&P::foo1, this);
functions["foo2"] = std::bind(&P::foo2, this);
functions["foo3"] = std::bind(&P::foo3, this);
}
void foo1(void)
{
std::cout << "foo1\n";
}
void foo2(void)
{
std::cout << "foo2\n";
}
void foo3(void)
{
std::cout << "foo3\n";
}
void call_by_name(const char* func_name)
{
functions[func_name]();
}
};
int main()
{
P p;
p.call_by_name("foo1");
p.call_by_name("foo2");
p.call_by_name("foo3");
}
You can use member function pointers like this (the C++11 is unrelated to that part):
struct S {
int foo(){std::cout<<"foo"; return 0;}
int bar(){std::cout<<"bar"; return 0;}
};
int main() {
std::vector<int(S::*)()> funcs{&S::foo, &S::bar};
S s;
for (auto func : funcs) {
(s.*func)();
}
}
However, if you use C++11, std::function can make it a bit cleaner:
std::vector<std::function<int(S &)>> funcs{&S::foo, &S::bar};
S s;
for (auto func : funcs) {
func(s);
}
If you use C++03, Boost has boost::function, which is similar.