I have the following problem. class A implements some routines that should be used on a dataset that is being processed in Class B. That means I'm calling the function start from class A. What I'm doing should be saved in a variable m in class A. So far so good. However, when accessing class variable m it is still on the state when initialized.
To be precise:
#include <iostream>
#include <functional>
class A {
public:
int m;
A() {
m = 100;
}
void start(int value) {
std::cout << "hello there!" << std::endl;
m = value;
}
};
class B {
private:
int m;
public:
void doSomething() {
A a;
doSomething2(std::bind(&A::start,a, std::placeholders::_1));
// access variable m of instance a
std::cout << a.m << std::endl;
}
template <typename Callable>
void doSomething2(Callable f) {
int val = 4444;
f(val);
}
};
main()
{
B b;
b.doSomething();
}
When executing this, I'll get 100 as an output for m. How will I be able to have the changes made by the call of start stored in the class variable? Meaning, storing the value 4444 as in this example? Thanks
Looks like you'll want to make sure that std::bind is using a pointer to the actual class instance you've created. Try changing it to:
// notice I've got '&a' here instead of just 'a'
doSomething2(std::bind(&A::start, &a, std::placeholders::_1));
Without this, I would guess what bind is doing now is making a copy of the a instance and then modifying that one instead of changing it in place.
Bind by default takes arguments by value, in result start() acts on a copy of object a. You have to pass it by reference:
doSomething2(std::bind(&A::start, std::ref(a), std::placeholders::_1));
Possible alternative is to use a lambda expression instead.
Related
I am learning C++ so maybe my question is dumb. I am creating a function that takes a lambda as a parameter. I just want to know if its safe to call it when the lambda function goes out of scope. With code is easier to explain what I mean:
struct SomeStruct
{
// store pointer to callback function
void (*callback)(bool);
int arg1;
int arg2;
};
void some_method(int arg1, int arg2, void (*on_complete_callback)(bool))
{
SomeStruct s;
s.callback = on_complete_callback;
s.arg1 = arg1;
s.arg2 = arg2;
// this helper class will copy the struct even though it is passed by reference
SomeHelperClass->SomeQueue.enqueue( &s );
// do work on a separate task/thread
SomeHelperClass->CreateThread([](){
// get copy of struct
SomeStruct s_copy;
SomeHelperClass->SomeQueue.dequeue( &s_copy );
// do work that takes time to complete
// IS IT SAFE TO CALL THIS CALLBACK FUNCTION?
s_copy.callback(true);
});
}
So my question is given that code if its safe to have something like this?
void method_1()
{
void (*foo)(bool) = [](bool completedCorrectly)
{
cout << "task completed :" << completedCorrectly << endl;
};
some_method(1,2,foo);
// at this point foo should be deleted no?
// why does this work if foo is executed after method_1 completes and its stack is deleted?
// can I have code like that?
}
Edit 2
Here is the same question with working code instead of pseudo code:
#include <iostream> //for using cout
using namespace std; //for using cout
// 3 pointers
int* _X; // points to integer
int* _Y; // points to integer
void (*_F)(int); // points to function
void print_values()
{
cout << "x=" << *_X << " and y=" << *_Y << endl;
}
void some_function()
{
// create variables that live on stack of some_function
int x = 1;
int y = 2;
void (*foo)(int) = [](int someInt)
{
cout << "value passed to lambda is:" << someInt << endl;
};
// point global variables to variables created on this stack x,y and foo
_X = &x;
_Y = &y;
_F = foo;
// works
_F(11);
// works
print_values();
// when exiting variables x,y and foo should be deleted
}
int main(void)
{
// call some function
some_function();
// DOES NOT WORK (makes sense)
print_values();
// WHY DOES THIS WORK? WHY FOO IS NOT DISTROYED LIKE X AND Y?
_F(10);
return 0;
}
If I where to call that method many times and each time with a different lambda will it work? Will the callback method call the correct lambda every time?
A lambda expression is like a class. It is a blueprint for instantiating objects. Classes exist only in source code. A program actually works with objects created from the blueprint defined by a class. Lambda expressions are a source code blueprint for creating closures. Each lambda expression is transformed into a class by the compiler and instantiated into an object called closure. This class has the ability to capture values (that's that the [] part does) and take parameters (that's that the () part does) for its call operator.
Here is an example:
int main()
{
int i = 42;
auto l = [i](int const x){std::cout << x+i << '\n';};
l(2);
}
The compiler transforms this into something similar to the following (generated with https://cppinsights.io/).
int main()
{
int i = 42;
class __lambda_6_11
{
public:
inline /*constexpr */ void operator()(const int x) const
{
std::operator<<(std::cout.operator<<(x + i), '\n');
}
private:
int i;
public:
__lambda_6_11(int & _i)
: i{_i}
{}
};
__lambda_6_11 l = __lambda_6_11{i};
l.operator()(2);
}
You can see here a class that implements the call operator (operator()) with an int argument. You can also see the constructor taking an argument of type int. And then you can see the instantiation of this class at the end of main and the invocation of its call operator.
I hope this helps you understand better how lambdas work.
I can't figure out how to call function pointer stored in std::array which is member of class.
namespace logic {
class Chance {
std::array<void(logic::Chance::*)(), 15> m_redChances;
};
}
void logic::Chance::redChance1 {
std::cout << "Red chance one\n";
}
logic::Chance::Chance()
{
m_redChances[0] = &Chance::redChance1;
}
It looks fine till now, but when I want to call this function in another member function, nothing seems to work. Only first line compiles, but it doesnt call my function. Rest are giving erros:
logic::Chance::anotherMemberFunction() {
m_redChances[0];
(*m_redChances[0]*)();
(*logic::Chance::m_redChances[0])();
m_redChances[0]();
*m_redChances[0]();
*logic::Chance::m_redChances[0]();
*logic::Chance::m_redChances[0];
*(*m_redChances[0])();
}
operand of "*"must be a pointer type
and
expression precending parentheses of apprent call must have
(pointer-to-) function type
EDIT#
So I tried to use std::function and had to change class design a bit, I want to achieve something like this
struct Foo {
std::array<std::function<void(Foo&)>, 3> funArray;
Foo() {
funArray[0] = &Foo::fun1;
funArray[1] = &Foo::fun2;
}
void fun1() {
std::cout << "fun1\n";
}
void fun2() {
std::cout << "fun2\n";
}
std::function<void(Foo&)> getFunction(int i) {
return funArray[i];
}
};
int main() {
Foo foo;
foo.getFunction(0);
std::cin.get();
}
As you can guess, this isn't calling my function and I again, tried every combination to return this correctly, but cant figure it out, thats the only one that compiles, but does nothing. How can I return a function call of function sotred in std::array by another function? A bit messy, but hope you get what I mean.
std::array<void(logic::Chance::*)(), 15> m_redChances is an array of pointers to a non-static member function of objects of class Chance. Therefore, you need to apply the object where the pointed-to member function is going to be called.
In the statement:
(*logic::Chance::m_redChances[0])();
no object is provided. On which object's data is that call going to be performed?
Considering chance an object of Chance and chance_ptr a pointer to an object of the same type, the call would be performed this way:
(chance.*m_redChances[0])();
(chance_ptr->*m_redChances[0])();
That is, by using the operators .* and ->*, respectively.
In your std::function example you can simply change
foo.getFunction(0);
to instead say
foo.getFunction(0)(foo);
This has to do with the same reason talked about in the other answers, a pointer to member-function is not in itself linked to an object. It needs a this to work on.
If you want to bind the std::function to a specific object you can use a
lambda to do that, like this.
#include <iostream>
#include <array>
#include <functional>
struct Foo {
std::array<std::function<void()>, 3> funArray; // Notice the change in signature to void()
Foo() {
funArray[0] = [&](){ fun1(); }; // Here & is catching this by reference and this lambda will always call fun1 on the current object.
funArray[1] = [&](){ fun2(); };
}
void fun1() {
std::cout << "fun1\n";
}
void fun2() {
std::cout << "fun2\n";
}
std::function<void()> getFunction(int i) {
return funArray[i];
}
};
int main() {
Foo foo;
foo.getFunction(0)(); // We get a function returned, so we need to call if by adding one more () at the end
auto storedFunction = foo.getFunction(1); // We can also store it
storedFunction(); // and call it later
}
A member function needs to be called on an object, to serve as the *this current object. You use the .* and ->* operators to call it with an object. E.g. (o.*mf)( args ).
Silly-fact noted by Andrei in his Modern C++ Programming book: o.*mf produces a callable entity that has no type.
In C++11 and later you can use std::function to effectively store such an object+function pointer pair, as a callable entity. Some other languages support it directly. E.g., it corresponds to a C# delegate.
Example.
#include <array>
#include <iostream>
using namespace std;
struct Foo
{
void blah() { cout << "Blah!" << endl; }
};
auto main()
-> int
{
array<void (Foo::*)(), 3> mf = {nullptr, nullptr, &Foo::blah};
Foo o;
Foo* o_ptr = &o;
(o_ptr->*mf[2])();
}
So, what i'm trying to do is this:
I would like to create a general class MyCLASS with a function genericFunction() which is empty by default. Now, when a co-worker wants to use this generic function, what he does is creating an instance of MyClass, and overriding genericFunction(), so it should give a resoult similar to this:
class MyClass{
public:
void genericFunction(){
//boring default actions
}
//constructor
MyClass(){
//do things
}
};
int main(){
MyClass instance();
//now we override the function, something like:
instance.genericFunction(){
cout << "This new code exists only for this instance, and has been created outside the class!";
}
instance.genericFunction();
return 0;
}
So that's basically what I would like to do.
In the case that it is not possible, how can i make my class run a function that is going to be later defined in main()?
Thanks a lot!
EDIT: To answer your questions:
*I'm new to c++ and it's true that my background is from other languages
*The idea is the following: You are creating objects that have a position, and if the position is in a certain range, genericFunction() is executed. The thing is that for each instance the function that is executed may (or in fact should) be different. The idea is 'inspired' by android's clickListener, where each element has a different function to execute when clicked
Thanks again!
If you want to be able to set user defined functions for a class object then you can give it a member variable of type std::function. Using slightly different syntax from your example it could look like this:
class MyClass
{
public:
std::function<void()> genericFunction = []{};
};
int main()
{
MyClass instance;
instance.genericFunction(); // does nothing
// assign a lambda function to our
// function member
instance.genericFunction = []
{
std::cout
<< "This new code exists only for this instance, and has been created outside the class!";
};
instance.genericFunction(); // executes our lambda function
}
EDIT
If you want to be able to pass parameters or receive a return value, then change the template signature to std::function like this:
class MyClass
{
public:
// take a string parameter and return an integer
std::function<int(std::string const&)> genericFunction = [](std::string const&){ return 0; };
};
int main()
{
MyClass instance;
int return_value;
return_value = instance.genericFunction("This will do nothing and return 0"); // does nothing
std::cout << "The first function returned: " << return_value << '\n';
// assign a lambda function to our
// function member
instance.genericFunction = [](std::string const& msg)
{
std::cout << msg << '\n';
return 5;
};
return_value = instance.genericFunction("This will pint a message and return 5"); // executes our lambda function
std::cout << "The second function returned: " << return_value << '\n';
}
I want to make a class where there is a function that is called automatically, to process information stored within this classes instance.
However each instance has different values and possibly a different way for that content to be handeled.
Therefore I need something simmilar to constructor overloading but in a member function. Where every instance can overload the default function or leave it up to the default to handle the input.
How can that be achieved?
Try to Call Functions in Constructor with if else condition
like:
class abc{
abc(){
if username == "member 1"
functioncall();
else
functioncall();
}
}
As far as I see you need some virtual construction emulation. There is a simple C/C++ way to do it.
// Example program
#include <iostream>
#include <string>
struct A;
typedef void (*cb)(A*);
struct A
{
int m_a;
static void foo(A* aref)
{
std::cout << "Print a: " << aref->m_a << "\n";
}
A(cb b=foo)
{
m_a = 100;
b(this);
}
};
int main()
{
A a;
}
It is not very clear, but still does the trick.
By creating a separate class for the variable behavior Callable describes the local data relating to the function, and by being a class, can be derived.
class Callable {
public:
int m_Value;
Callable(int value) : m_Value(value)
{
}
void operator()( int val1, double val2 /* whatever makes sense */ ) {
}
};
Using the function operator void operator()( ...... ) we create a way of making variables of type Callable to look like a function.
class Variable {
public:
Callable myFunction;
Variable(const Callable & howToCall, /* some more stuff */) :
myFunction(howToCall)
{ /* stuff */
}
void aFunction(int data, double value ) {
myFunction( data, value);
}
};
When calling aFunction the current value of myFunction is called.
Finally Variable can change which function it calls, by modifying the value of myFunction....
myFunction = Callable( /* new parameters */ );
I want to use boost::call_once() to achieve a thread-safe lazy-construction
singleton scenario, however, the base singleton class has many derived classes thus the getInstance() function takes an argument to determine which derived class to initialize. The code looks like,
Singleton * Singleton::getInstance(Input * a) {
if (!instance) {
instance = buildme(a); //buildme() will return a derived class type based on input a.
}
return instance;
}
I want to use boost::call_once(), but looks like it can only be used on functions with no arguments void (*func)(). If anybody knows about an alternative solution here please help.
Thanks.
EDIT::
Another question, how to call a non-static member function using call_once? I have a non-static init() member function of this class, but I couldn't find a correct syntax for calling it using boost::call_once(). Or should I make init() and everything used in it static?
Thanks.
C++11 contains an implementation of call_once (inspired by the equivalent Boost.Threads facility). It uses variadic templates and perfect forwarding to take an arbitrary number of arguments.
#include <mutex>
#include <string>
void only_called_once(int i, std::string const & str) {
// We only get here once.
}
void call_free() {
static std::once_flag once;
std::call_once(once, only_called_once, 42, "The answer");
}
You can pass an arbitrary number of arguments after the callable and they will all be perfectly forwarded (including r-value/l-value, const, volatile, etc).
This also works for member functions. You just have to pass a pointer to an object (convertible to the type the member function belongs to) as the first argument after the callable.
struct bar {
public:
void only_call_once(int i, std::string const & str);
};
void call_member() {
static std::once_flag once;
bar instance;
std::call_once(once, &bar::only_call_once, &instance, 42, "The answer");
}
If you are stuck with Boost then you can use boost::bind for the same purpose as has already been explained in another answer. Member functions with boost::bind work the same way as above by passing a member function pointer and an instance as the following parameter.
You can bind additional function parameters to a functor object using boost::bind. Like this:
Input* input = ???;
boost::call_once(flag, boost::bind(&Singleton::getInstance, input));
You can use boost::bind to call non-static member functions as well, by passing the instance of the class on which you want to call the function to boost::bind.
class Foo
{
public:
void func(int) { /* do something */}
};
Foo f;
boost::call_once(flag, boost::bind(&foo::func, &f, 10));
With C++11, you can use std::bind, here's another example. boost::bind is quite similar.
#include <utility>
#include <functional>
#include <iostream>
#include <string>
void f(int x)
{
std::cout << "f(" << x << ")\n";
}
void g(int x, const std::string& y)
{
std::cout << "g(" << x << ", " << y << ")\n";
}
int main()
{
auto ten = std::bind(&f, 10);
auto example = std::bind(&g, 20, "Twenty");
ten();
example();
return 0;
}