I want to call function either with default arguments or given by me, but default arguments are specified class private variables, simplified sample here:
Class::Something
{
public:
void setI(int i);
private:
void func(int i = this->i_default, j=this, k=this->k_default, l=this->l_default);
int i_default; // May be different for different instances.
int k_default; // May be different for different instances.
int l_default; // May be different for different instances.
}
So when i call func() it takes default i_variable or when i call func(4) it takes 4 argument without changing i_default value.
I know im doing something wrong couse i get error:
Error 1 error C2355: 'this' : can only be referenced inside non-static member functions or non-static data member initializer
is there some kind of way to achive such behaviour?
is there some kind of way to achive such behaviour?
Use function overload (Thanks #PiotrSkotnicki):
void func(int i);
void func() { func(i_default); }
You can declare i_default as const static (Thanks to #TartanLama).
const static int i_default=1;
Here is the working program.
You can also use function overloading. But this uses less code than function overloading!
The standard is quite clear about this. You explicitely cannot use this in the default parameter. You seem to be bound to use overloading for achieving this result:
void func(int i);
void func() { func(i_default); }
If you want to keep down the functions you could use a sentry that would allow func decide if it's to use the default. In the simpliest form:
void func(int* pi = NULL) {
int i = pi ? *pi : i_default;
// rest of the function
}
This method could be extended to use a helper class:
#include <cstdio>
template <typename C, typename T>
class Defaltable {
T val;
T C::* ptr;
public:
Defaltable(int C::* p) {
ptr = p;
val = 0;
}
Defaltable(T x) {
val = x;
ptr = NULL;
}
T fetch(C* p) {
return ptr ? p->*ptr : val;
}
};
class Foo {
int i_default;
public:
Foo(int dflt) {
i_default = dflt;
}
int func(Defaltable<Foo, int> x = &Foo::i_default) {
return x.fetch(this);
}
};
int main()
{
Foo c(42);
printf("%d\n", c.func(1));
printf("%d\n", c.func());
}
Related
I have a class that has function pointer to kernel function, that can change from outside.
class Bar
{
public:
int i;
}
class Foo
{
public:
std::function<double()> kernel;
Bar bar;
};
int main()
{
Foo f;
f.kernel = []() -> double { return i * i; }; //this is not working obviously
}
How can I achieve behaviour that is "presented", eg. read class variables inside lambda. I can bypass it by passing f inside and write f.bar.i, but that is not very nice solution.
In C++14 you can write it as,
f.kernel = [&i = f.bar.i]() -> double { return i * i; };
If you don't have C++14, you can alternatively create another variable,
int &i = f.bar.i;
f.kernel = [&i]() -> double { return i*i; };
Though there's nothing wrong with passing f and writing f.bar.i.
It seems that you cannot do so.
There is no construct to create a member function lambda.
But you probably can follow #KerrekSB's suggestion and in addition to that dispatch the call to still get the member function:
class Foo
{
public:
double kernel()
{
_kernel(*this);
}
std::function<double(Foo &)> _kernel;
};
Foo f;
f._kernel = [](Foo &f) -> double { return f.i * f.i; };
f.kernel()
Note that you cannot name both fields kernel.
The lambda function does not know about i or Bar. How could it know? You need to pass a Reference. If you define the function body differently so you can pass i as parameter and you call it within the class you should get what you want.
Using c++11
I want to create a class that uses a lambda as part of a calculation.
//contrived sample of potential usage
void random_class::some_function(void)
{
auto an_object = new my_custom_object(5, [this](){ return random_class_member * 5; });
an_object.do_some_processing();
random_class_member++;
an_object.do_some_processing();
}
I am not quite sure how to go about declaring and defining my_custom_object.
class my_custom_object
{
public:
template <typename Proc>
my_custom_object(int a, Proc p)
{
privatea = a;
privatep = p;
}
void do_some_processing()
{
privatea += privatep();
}
private:
int privatea;
Proc privatep;
}
unknown type name 'Proc'
There are two approaches you could take.
Use a type-erased std::function
For example:
class my_custom_object {
public:
my_custom_object(int a, std::function<void()> p)
{
privatea = a;
privatep = p;
}
void do_some_processing()
{
privatea += privatep();
}
private:
int privatea;
std::function<void()> privatep;
};
This allows my_custom_object to accept any function-like thing that accepts no parameters. There is some performance overhead though, since the calls to privatep have to be resolved at runtime. This is likely negligible, but it could matter if this is happening in a tight loop in a performance-critical section of your program though.
The call site would look exactly as you have it now:
void random_class::some_function(void)
{
my_custom_object an_object{5, [this](){ return random_class_member * 5; }};
an_object.do_some_processing();
random_class_member++;
an_object.do_some_processing();
}
Template my_custom_object on the type of function it holds.
For example:
template <typename Proc>
class my_custom_object {
public:
my_custom_object(int a, Proc p)
{
privatea = a;
privatep = p;
}
void do_some_processing()
{
privatea += privatep();
}
private:
int privatea;
Proc privatep;
};
This will allow your calls to privatep to be resolved statically at compile time, which may have slightly better performance than using std::function. This does mean that the type of Proc is now part of the type of my_custom_object though, so it's a bit less flexible in some situations.
Since C++17 added class template argument deduction, the call site would look exactly the same:
void random_class::some_function(void)
{
my_custom_object an_object{5, [this](){ return random_class_member * 5; }};
an_object.do_some_processing();
random_class_member++;
an_object.do_some_processing();
}
If you have to use a pre-C++17 compiler you'll have to specify the template parameter to my_custom_object explicitly:
void random_class::some_function(void)
{
auto func = [this](){ return random_class_member * 5; };
my_custom_object<decltype(func)> an_object{5, func};
an_object.do_some_processing();
random_class_member++;
an_object.do_some_processing();
}
If the signature of the lambda is fixed you can remove the template and use std::function<ReturnType(parameters)>. In your case
using Proc = std::function<int(void)>;
should work. Then you can pass a lambda that takes no arguments and returns an int.
I have a function that runs a callback:
void run_callback(void(*callback)(uint32_t)) {
callback(100);
}
This works with static functions,
void global_callback(uint32_t);
int main() {
run_callback(global_callback);
}
but not with member functions.
class A {
int x;
public:
void callback(uint32_t);
};
int main() {
A foo;
run_callback(foo.callback);
}
I work around this with a static wrapper function.
void run_member_callback(void* obj, void(*callback)(void*,uint32_t)) {
callback(obj, 100);
}
class B {
int x;
public:
static void static_callback(void* obj, uint32_t value) {
static_cast<B*>(obj)->callback(value);
}
void callback(uint32_t);
};
int main() {
B foo;
run_member_callback(&foo, foo.static_callback);
}
Is there a simple way to pass a member function as an argument?
edit:
I'm trying to avoid STL, and templates aren't an option since my implementation of run_callback is virtual.
You are doing some weird, C-ish things. Use C++ features. I personally would use a template for run_callback and a lambda for passing the member function:
template <class F>
void run_callback(F callback)
{
callback(100);
}
class A
{
int x;
public:
void callback(uint32_t);
};
int main()
{
A foo{};
run_callback([&](uint32_t a) { return foo.callback(a); });
}
If you capture the object by reference take care it outlives the run_callback call. Otherwise capture it by value.
What is a lambda expression in C++11?
Let's suppose I have the following function interface:
void giveme(void (*p)());
That function simply accepts a pointer to a function with no return type and argument.
I'm wondering if exists a way (without change the interface) to pass a class method as parameter of that function.
I'll try to explain better with an example. I have a class, like:
class Foo {
public:
template<typename T>
void bar();
};
I want to pass bar<T> (of an addressable instance of the class) as parameter of the function giveme.
I thought to bind the method with an object, and obtain the function target.
Something like:
int main(int argc, char *argv[]) {
Foo foo;
std::function<void()> f = std::bind(&Foo::bar<int>, &foo);
giveme(f.target<void()>());
return 0;
}
It compiles, but obviously does not work because, from here:
TargetType shall match the target type, so that typeid(TargetType)==target_type(). Otherwise, the function always returns a null pointer.
So, if exists, what is a way to achieve it?
Here's one (very bad) idea:
Foo * foo_ptr; // maybe thread_local
void foo_call()
{
foo_ptr->bar<int>();
}
int main()
{
Foo foo;
foo_ptr = &foo;
give_me(&foo_call);
}
It's not pretty, but neither is your situation.
There's only one way I know of, and it's a terrible idea, and don't do this.
typedef void (*void_fn)();
struct stateful_void_fn_data = {
void_fn raw;
std::function<void()> actual;
std::atomic_bool in_use;
}
// a global array to hold your function bindings and such
extern stateful_void_fn_data stateful_functions[5];
// N stateless functions that defer to the correct global state
template<int n> void void_fn_impl() {stateful_functions[n].actual();}
extern stateful_void_fn_data stateful_functions[5] =
{{void_fn_impl<0>}, {void_fn_impl<1>}, {void_fn_impl<2>}, {void_fn_impl<3>}, {void_fn_impl<4>}};
// function to register a stateful and get a stateless back
void_fn allocate_void_fn(std::function<void()>&& f) {
for(int i=0; i<5; i++) {
if(stateful_functions[i].in_use.compare_exchange_weak(false, true)) {
stateful_functions[i].actual = std::move(f);
return stateful_functions[i].raw;
}
}
throw std::runtime_error("ran out of stateful functions :(");
}
// function to unregister
void free_void_fn(void_fn f) {
if (f == nullptr) return;
for(int i=0; i<5; i++) {
if (stateful_functions[i].raw == f) {
stateful_functions[i].in_use = false;
return;
}
}
throw std::runtime_error("unknown void function");
}
Basically, I generate 5 void() functions (void_fn_impl<N>), and each calls a function stored in one of the five a global array slots (stateful_functions[i].actual). Then, allocate_void_fn will store any std::function<void()> in the global array, and hand you the void() that calls that entry in the array. This function itself is stateless, because we've stored all the state in the global array. free_void_fn and in_use exist solely to make the functions reusable.
And of course, because RAII is good:
class hidden_state_void_fn {
void_fn raw;
public:
hidden_state_void_fn(std::function<void()>&& f)
:raw(allocate_void_fn(std::move(f)) {}
hidden_state_void_fn(const hidden_state_void_fn&& r) {
raw = r.raw;
r.raw = nullptr;
}
hidden_state_void_fn& operator=(const hidden_state_void_fn&& r) {
free_void_fn(raw);
raw = r.raw;
r.raw = nullptr;
}
~hidden_state_void_fn() {free_void_fn(raw);}
operator void_fn() {return raw;}
operator()() {raw();}
};
std::map<int,std::function<void()>> tasks;
template<int n>
struct task_wrapper{
static void f(){ if (tasks.count(n)) tasks[n](); }
task_wrapper(std::function<void()> fin){ tasks[n]=fin; }
~task_wrapper(){ tasks.erase(n); }
static std::shared_ptr< void(*)() > make(std::function<void()> fin){
auto self=std::make_shared<task_wrapper>(fin);
return { &f, fin };
}
};
A task_wrapper<N>::make(func) return a shared pointer to a stateless function pointer that will call the stateful func.
We can use the the usual techniques to create an array of K function pointers of signature shared_ptr<void(*)()>(*)(). Then we can have a shared_ptr<void(*)()> register_func( std::function<void()> ).
To find blanks, we can either do a linear search, or we could build a table of blanks. This could look like a traditional allocation/free "heap", or a range-tree of blanks, or whatever.
Another approach would be to literally create and save a DLL on the fly then load it and call the symbol. This could be done via hacks (have such a DLL and a known offset to modify, copy and write, then load and run) or by shipping a C++ compiler (or other compiler) with your code (!).
I want to achieve something like this:
class C
{
int m_nVal;
public:
C(int nVal) : m_nVal(nVal){}
void foo(int nVal = m_nVal)
{
// use nVal, if provided; otherwise use m_nVal
}
};
C c(1);
c.foo(); // use 1
c.foo(2); // use 2
This is not possible as C++ standard says:
a non-static member shall not be used in a default argument
Options I have are:
(1) Overload foo():
class C
{
int m_nVal;
public:
C(int nVal) : m_nVal(nVal){}
void foo()
{
// use m_nVal
}
void foo(int nVal)
{
// use nVal
}
};
(2) Use static member:
class C
{
static int m_nVal;
public:
void foo(int nVal = m_nVal)
{
// use nVal, if provided; otherwise use m_nVal
}
};
I don't want to make m_nVal static member so option 1 seem the only one.
Are there any other ways to achieve this?
There are other alternatives if you are willing to change the interface. You can use boost::optional:
// untested:
void foo( boost::optional<int> val = boost::optional<int>() ) {
int value;
if ( val ) value = *val;
else value = m_val;
// Now use `value` in the function
}
If you cannot use boost, you can write your own nullable wrapper. You just need to store the type (int) and a flag that determines whether it is set or not.
The next option is using a pointer to mark that the argument is optional:
void foo( int *pval = 0 ) {
int value = (pval? *pval : m_val);
// use value from here on
}
But the option with the pointer inhibits the use of rvalues as arguments to the function (i.e. you need a proper variable to call the function, you cannot do foo(1) but rather need to do int x = 1; foo( &x );, which is kind of a pain).
Finally you can use your approach of offering two overloads, one that takes the argument and one that doesn't and just forwards to the first:
void foo( int val ) {
// actual implementation
}
void foo() {
foo( m_val );
}
This might actually be the best option...
The two options aren't equivalent. Making a member static shouldn't be a decision made on whether you want to use it as a default to a method or not.
If m_nVal is logically bound to the class, and not an instance, make it static.
If m_nVal is specific to each object of the class, don't, and use the first option.
Passing default parameter would mean compiler has to pass it. It would mean, for m_nVal, the compiler would use this->m_nVal. This would, in turn, mean `foo(this->m_nVal);'.
This is what I mean:
c.foo(c.m_nVal); // use 1
Which would allow m_nVal private data to be accessed outside class, and breaks basic C++ rule.
class C
{
int m_nVal;
public:
C(int nVal) : m_nVal(nVal){}
void foo(int nVal = -1)
{
if(nVal == -1)
nVal = m_nVal;
// use nVal, if provided; otherwise use m_nVal
}
};
C c(1);
c.foo(); // use 1
c.foo(2); // use 2