Start thread with member function (with inheritance) - c++

So my problem starts pretty much like this question:
Start thread with member function
I have some class Foo, that looks like this:
struct Foo
{
int y;
thread t;
void set(int x){
y = x;
}
void plan(int x){
thread = std::thread ([&]{
set(x);
});
void get(){
if (t.joinable())
t.join();
}
};
Other answers also suggest:
void plan(int x){
thread = std::thread(&Foo::set, this, x);
};
Now, I want to use Foo as a base class for various child class with overloaded set() functions, for exemple:
struct Bar: public Foo
{
void set(int x){
y = x*2;
}
}
My problem is that if done that way, Bar::plan() result in Foo::set() being runned in the new thread instead of Bar::set as expected.
Is there another solution than having to write again the plan() method in every child class of Foo?

You might simply make set virtual:
struct Foo
{
// ...
virtual void set(int x);
};
struct Bar : Foo
{
void set(int x) override;
};

Just mark set as virtual and use the lambda version, being careful to capture everything by value, as the plan invocation may (and probably will) return before the thread actually start to run.
struct Foo
{
int y;
thread t;
virtual void set(int x){
y = x;
}
void plan(int x){
t = std::thread ([this, x]{
this->set(x);
});
}
void get(){
if (t.joinable())
t.join();
}
};
this will call the correct set version even when plan is invoked in a derived class.

Though the answer has been accepted already, Here is a way to do the same using std::bind.
#include <iostream>
#include <thread>
#include <functional>
using namespace std;
struct Foo
{
int y;
thread t;
virtual void set(int x){
y = x;
}
void plan(int x){
t = std::thread (std::bind(&Foo::set, this, x));
}
void get(){
if (t.joinable())
t.join();
}
};
struct Bar: public Foo
{
void set(int x){
cout << "Called" << endl;
y = x*2;
}
};
int main() {
Bar b;
b.plan(2);
b.get();
return 0;
}
Also, Without using lambda, you could have done this also:
void plan(int x){
t = std::thread (&Foo::set, this, x);
}

Related

Is there a way to use one function to replace two similar functions in C++

The following code compiles and runs fine. But, to me, there are repeated code in funtions workflow1 and workflow2.In fact, the only differences are the added parameter y in workflow2, and the different calls to method1/method2. Is there a way to use one function to replace those two? Maybe there is a way to pass a function (workflow1 or workflow2) and its parameters as parameters to another general function (say, workflow)? Maybe there exist some design patterns for this kind of job?
class MyClass
{
public:
void workflow1(int x) {
doThings(); // actually some code more than just one function call
method1(x);
doOtherThings(); // actually some code more than jus one function call
}
void workflow2(int x, int y=1) {
doThings(); // actually some code; the same as in workflow1()
method2(x,y);
doOtherThings(); // actually some code; the same as in workflow1()
}
private:
void doThings() {}
void doOtherThings() {}
void method1(int x) {}
void method2(int x, int y) {}
};
int main()
{
MyClass myClass;
int x = 0;
myClass.workflow1(x);
int y = 2;
myClass.workflow2(x, y);
}
Two options:
Use a lambda approach:
#include <functional>
class MyClass
{
public:
void workflow1(int x) {
workFlowInternal([x, this] {method1(x); });
}
void workflow2(int x, int y = 1) {
workFlowInternal([x, y, this] {method2(x,y); });
}
private:
void workFlowInternal(const std::function<void()> &func) {
doThings();
func();
doOtherThings();
}
void doThings() {}
void doOtherThings() {}
void method1(int x) {}
void method2(int x, int y) {}
};
Or, use a pointer to member function:
class MyClass
{
public:
void workflow1(int x) {
workFlowInternal(&MyClass::method1, x, 0);
}
void workflow2(int x, int y = 1) {
workFlowInternal(&MyClass::method2, x, y);
}
private:
void workFlowInternal(void(MyClass::* func)(int, int), int x, int y) {
doThings();
(this->*func)(x,y);
doOtherThings();
}
void doThings() {}
void doOtherThings() {}
void method1(int x, int ignored=0) {}
void method2(int x, int y) {}
};
You can just use std::optional:
#include <optional>
class MyClass
{
public:
void workflow(int x, std::optional<int> y = {}) {
doThings();
if (!y) method1(x);
else method2(x, *y);
doOtherThings();
}
private:
void doThings() { }
void doOtherThings() { }
void method1(int x) { }
void method2(int x, int y) { }
};
int main() {
MyClass myClass;
int x = 0;
myClass.workflow(x);
int y = 2;
myClass.workflow(x, y);
}
Demo.
You can write a templated function like this:
template <bool workflow1>
void Workflow(int x, int y=1)
{
doThings();
if constexpr (workflow1)
{
method1(x);
}
else
{
method2(x, y);
}
doOtherThings();
}
int main()
{
int x = 0;
Workflow<true>(x);
int y = 2;
Workflow<false>(x, y);
}
if constexpr statements are decided at compile time, so this will generate two different functions, but you won't have to rewrite the code that is the same. The template argument can be changed from a bool to an enum or another type if you need to support more than two types.

Storing functions from class in array and invoke them c++

i try store a functions(methods) from class in array and use them.
The error handle is
In function 'int main()':| 'actions' was not declared in this
scope
this my code(i delete unnecessary code)
the class.h:
class Calculator
{
public:
int num1,num2;
void (Calculator::*actions[4])();
void add();
void minuz();
void multi();
void div();
Calculator();
};
class.cpp:
void Calculator::add()
{}
void Calculator::minuz()
{}
void Calculator::div()
{ }
void Calculator::multi()
{}
Calculator::Calculator()
{
actions[0]=add;
actions[1]=minuz;
actions[2]=div;
actions[3]=multi;
}
main:
Calculator cal;
.....
.....
cal.*actions[num]();
C++ syntax for function pointer declaration is quite complicated, so it better use typedefs
To call function by pointer you need extra () around dereferenced function pointer.
Finally it will be:
class Calculator
{
public:
typedef void (Calculator::*action)();
int num1,num2;
action actions[4];
void add();
void minuz();
void multi();
void div();
Calculator();
};
void Calculator::add()
{}
void Calculator::minuz()
{}
void Calculator::div()
{ }
void Calculator::multi()
{}
Calculator::Calculator()
{
actions[0]=&Calculator::add;
actions[1]=&Calculator::minuz;
actions[2]=&Calculator::div;
actions[3]=&Calculator::multi;
}
int main(int, char**) {
Calculator cal;
int num = 0;
(cal.*cal.actions[num])();
return 0;
}
for better readability I'd suggest add function Calculator::call_by_index(int):
void Calculator::call_by_index(int index)
{
(this->*actions[index])();
}
and call it in such way:
cal.call_by_index(num);
Using a typedef usually helps: (c++03)
Live On Coliru
class Calculator
{
public:
int num1,num2;
typedef void (Calculator::*Action)();
Action actions[4];
Calculator() {
actions[0]=&Calculator::add;
actions[1]=&Calculator::minuz;
actions[2]=&Calculator::div;
actions[3]=&Calculator::multi;
}
private:
void add() {}
void minuz() {}
void multi() {}
void div() {}
};
int main() {
Calculator cal;
(cal.*cal.actions[1])();
}
C++11 aliases
C++11 makes it easier:
using Action = void (Calculator::*)();
Action actions[4];
See also https://isocpp.org/wiki/faq/pointers-to-members#fnptr-vs-memfnptr-types
Live On Coliru
std::function<>
Also in c++11 (or boost if you want it in c++03):
using Action = std::function<void(Calculator&)>;
Action actions[4];
Which you would still call like
cal.actions[1](cal);
I'd pre-bind to the Calculator instance:
Live On Coliru
#include <functional>
class Calculator
{
public:
int num1,num2;
using Action = std::function<void()>;
Action actions[4];
Calculator() {
actions[0] = [this]() { add(); };
actions[1] = [this]() { minuz(); };
actions[2] = [this]() { multi(); };
actions[3] = [this]() { div(); };
}
private:
void add() {}
void minuz() {}
void multi() {}
void div() {}
};
int main() {
Calculator cal;
cal.actions[1]();
}
You're not calling it right. Since actions is a member of Calculator, you need to reference a Calculator object to get at it.
(cal.*(cal.actions[num]))();
The first cal is the object you're wanting to call the action with, and the second cal is used to access the action you want to call.

Avoid the class scope so as to pass a member function as a function pointer

I'll describe my question using the following sample code.
I have class B defined as follows:
class B
{
public:
inline B(){}
inline B(int(*f)(int)) :myfunc{ f }{}
void setfunction(int (*f)(int x)) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
int(*myfunc)(int);
};
I then define class A as follows:
class A
{
public:
A(int myint) :a{ myint }{ b.setfunction(g); }
int g(int) { return a; }
void print() { b.print(a); }
private:
B b;
int a;
};
To me the issue seems to be that the member function g has the signature int A::g(int) rather than int g(int).
Is there a standard way to make the above work? I guess this is quite a general setup, in that we have a class (class B) that contains some sort of member functions that perform some operations, and we have a class (class A) that needs to use a particular member function of class B -- so is it that my design is wrong, and if so whats the best way to express this idea?
You can use std::function:
class B
{
public:
inline B() {}
inline B(std::function<int(int)> f) : myfunc{ f } {}
void setfunction(std::function<int(int)> f) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
std::function<int(int)> myfunc;
};
class A
{
public:
A(int myint) :a{ myint } {
b.setfunction([this](int a) {
return g(a);
}
);
}
int g(int) { return a; }
void print() { b.print(a); }
private:
B b;
int a;
};
You could generalize the class B. Instead of keeping a pointer (int(*)(int)), what you really want is any thing that I can call with an int and get back another int. C++11 introduced a type-erased function objection for exactly this reason: std::function<int(int)>:
class B
{
using F = std::function<int(int)>
public:
B(){}
B(F f) : myfunc(std::move(f)) { }
void setfunction(F f) { myfunc = std::move(f); }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
F myfunc;
};
And then you can just provide a general callable into B from A:
A(int myint)
: b([this](int a){ return g(a); })
, a{ myint }
{ }
Use std::function and std::bind
class B
{
public:
inline B(int(*f)(int)) :myfunc{ f }{}
void setfunction(std::function<int(int)> f) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
std::function<int(int)> myfunc;
};
// ...
A a;
B b(std::bind(&A::g, &a));
Also note that you should initialize the function pointer to some default value (most likely null) and check for it when using, otherwise it's value is undefined.
You could use std::bind to bind the member function A::g.
class B
{
public:
inline B(){}
inline B(std::function<int(int)> f) :myfunc{ f }{}
void setfunction(std::function<int(int)> f) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
std::function<int(int)> myfunc;
};
class A
{
public:
A(int myint) :a{ myint } {
b.setfunction(std::bind(&A::g, this, std::placeholders::_1));
}
int g(int) { return a; }
void print() { b.print(a); }
private:
B b;
int a;
};
Note you need to change the type of functor from function pointer to std::function, which is applicable with std::bind.
LIVE

Using an interface class as member type in another class

I'm trying to design a piece of code that entails the use of an algorithm. The algorithm should be easily replaceable by someone else in the future. So in my LargeClass there has to be a way to invoke a specific algorithm.
I provided some example code below. My idea was to make an interface class IAlgorithm so that you have to provide an implementation yourself. I thought you could initialize it to which ever derived class you wanted in the constructor of the LargeClass. However the below code doesn't compile in VS2015 because IAlgorithm: cannot instantiate abstract class
My question: How should I design this in order to get the result I want?
Thanks in advance!
Algorithm.h
class IAlgorithm
{
protected:
virtual int Algorithm(int, int) = 0;
};
class algo1 : public IAlgorithm
{
public:
virtual int Algorithm(int, int);
};
class algo2 : public IAlgorithm
{
public:
virtual int Algorithm(int, int);
};
Algorithm.cpp
#include "Algorithm.h"
int algo1::Algorithm(const int a, const int b)
{
// Do something
}
int algo2::Algorithm(const int a, const int b)
{
// Do something
}
Source.cpp
#include "Algorithm.h"
class LargeClass
{
private:
IAlgorithm algo;
};
int main()
{
}
My first thoughts on this would be, why use such a primitive interface?
OK, we have a requirement that some process needs an algorithm sent into it. This algorithm must be polymorphic, it must take two ints and return an int.
All well and good. There is already a construct for this in the standard library. It's call a std::function. This is a wrapper around any function object with a compatible interface.
example:
#include <functional>
#include <iostream>
class LargeClass
{
public:
using algorithm_type = std::function<int(int,int)>;
LargeClass(algorithm_type algo)
: _algo(std::move(algo))
{}
int apply(int x, int y) {
return _algo(x,y);
}
private:
algorithm_type _algo;
};
int test(LargeClass&& lc) {
return lc.apply(5,5);
}
int divide(int x, int y) { return x / y; }
int main()
{
// use a lambda
std::cout << test(LargeClass{ [](auto x,auto y){ return x + y; } });
// use a function object
std::cout << test(LargeClass{ std::plus<>() } );
// use a free function
std::cout << test(LargeClass{ divide } );
// use a function object
struct foo_type {
int operator()(int x, int y) const {
return x * 2 + y;
}
} foo;
std::cout << test(LargeClass{ foo_type() } );
std::cout << test(LargeClass{ foo } );
}

Boost function and boost bind: Bind the return value?

This is related to this previous question: Using boost::bind with boost::function: retrieve binded variable type.
I can bind a function like this:
in .h:
class MyClass
{
void foo(int a);
void bar();
void execute(char* param);
int _myint;
}
in .cpp
MyClass::bar()
{
vector<boost::function<void(void)> myVector;
myVector.push_back(boost::bind(&MyClass::foo, this, MyClass::_myint);
}
MyClass::execute(char* param)
{
boost::function<void(void)> f = myVector[0];
_myint = atoi(param);
f();
}
But how can I bind a return value ? i.e.:
in .h:
class MyClass
{
double foo(int a);
void bar();
void execute(char* param);
int _myint;
double _mydouble;
}
in .cpp
MyClass::bar()
{
vector<boost::function<void(void)> myVector;
//PROBLEM IS HERE: HOW DO I BIND "_mydouble"
myVector.push_back(boost::bind<double>(&MyClass::foo, this, MyClass::_myint);
}
MyClass::execute(char* param)
{
double returnval;
boost::function<void(void)> f = myVector[0];
_myint = atoi(param);
//THIS DOES NOT WORK: cannot convert 'void' to 'double'
// returnval = f();
//MAYBE THIS WOULD IF I COULD BIND...:
// returnval = _mydouble;
}
If what you want is a nullary function that returns void but assigns a value to _myDouble with the result of foo() before doing so, then you cannot do this easily with just Boost.Bind. However, Boost has another library specifically catered to this sort of thing -- Boost.Phoenix:
#include <iostream>
#include <vector>
#include <boost/function.hpp>
#include <boost/phoenix/phoenix.hpp>
struct MyClass
{
MyClass() : _myVector(), _myInt(), _myDouble() { }
void setMyInt(int i);
void bar();
void execute();
private:
double foo(int const a) { return a * 2.; }
std::vector<boost::function<void()> > _myVector;
int _myInt;
double _myDouble;
};
void MyClass::setMyInt(int const i)
{
_myInt = i;
}
void MyClass::bar()
{
using boost::phoenix::bind;
_myVector.push_back(
bind(&MyClass::_myDouble, this) =
bind(&MyClass::foo, this, bind(&MyClass::_myInt, this))
);
}
void MyClass::execute()
{
if (_myVector.empty())
return;
_myVector.back()();
double const returnval = _myDouble;
std::cout << returnval << '\n';
}
int main()
{
MyClass mc;
mc.bar();
mc.setMyInt(21);
mc.execute(); // prints 42
mc.setMyInt(3);
mc.execute(); // prints 6 (using the same bound function!)
// i.e., bar has still only been called once and
// _myVector still contains only a single element;
// only mc._myInt was modified
}
problem 1: myVector needs to be a class member.
problem 2: myVector is interested in functions that return doubles and take no arguments, which would be boost::function<double()>
then, to bind _mydouble to the parameter of foo, call boost::bind(&MyClass::foo, this, MyClass::_mydouble) which should give you a compilation warning about casting a double to an int for when foo is called.
The closest you can come with Boost.Bind is providing the toreturn as a parameter.
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
using namespace std;
class Foo {
int myInt;
double myDouble;
public:
Foo() : myInt(3), myDouble(3.141592) { }
void SetToMyInt(double& param)
{
param = myInt;
}
void SetToMyDouble(double& param)
{
param = myDouble;
}
double Execute()
{
double toReturn = 2;
boost::function<void(double&)> f = boost::bind(&Foo::SetToMyDouble, this, _1);
f(toReturn);
return toReturn;
}
};
int main() {
Foo foo;
std::cout << foo.Execute() << std::endl;
return 0;
}