c++ class using a lambda in constructor - c++

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.

Related

Is it possible in C++14 to capture specific member variables by reference [duplicate]

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.

How to have the compiler deduce the return type of a templated method in C++11?

I have a templated-method where the return-type is will be the result of a reinterpret_cast<>()-call.
class A {
void *_ptr;
public:
template<typename T>
T buffer() { return reinterpret_cast<T>(_ptr); }
};
This way makes me use the <>-syntax when calling this function:
A a;
auto b = a.buffer<double *>();
I'd prefer to call this method without the template arguments and let the compiler deduce the return type, based on the variable-type.
A a;
double *out = a.buffer();
Is this possible with return-type deduction?
I tried using auto, the->-operand and the trailing return type syntax.
auto buffer() -> decltype(reinterpret_cast<T>(_ptr)) const
{ return reinterpret_cast<T>(_ptr); }
but it still doesn't work.
Is there any way doing this, in C++11?
Yes, but only via a proxy type having a conversion function template:
struct BufferProxy {
void* ptr;
template<class T> operator T*() { return reinterpret_cast<T*>(ptr); }
};
BufferProxy buffer() { return BufferProxy{_ptr}; }
Example.
Note that users who have become familiar with the use of auto for return type deduction are likely to become confused by this technique:
auto out = a.buffer(); // out is BufferProxy
auto* out = a.buffer(); // fails to compile; can't deduce 'auto*' from 'a.A::buffer()'
Up until C++17, you can prevent auto out = a.buffer(); from compiling by giving BufferProxy a deleted copy constructor (and perhaps returning it by aggregate construction: return {_ptr};), but the user could still use auto&& and from C++17 guaranteed copy elision will make the auto form work again.
You may want a class something like the following. This would seem to offer most of what you want to do.
One issue I was wondering about was how to determine if a pointer stored into the class was the same type or not. So I thought it would be best to add an additional method to check the typeid() using the hash_code() method.
So the class I came up with using the operator idea of #ecatmur in his/her answer:
class A {
void *_ptr;
size_t _ptrHash;
public:
template<typename T> operator T*() { return reinterpret_cast<T *>(_ptr); }
template<typename T>
void SetPtr(T *p) { _ptr = p; _ptrHash = typeid(*p).hash_code(); }
template<typename T> bool operator == (T *p) { return p && typeid(*p).hash_code() == _ptrHash /* && p == _ptr */; }
};
The equality operator could either check only the type as above or if you uncomment the additional check, also check for value of the pointer. You probably just want to check for the type.
A simple demo function that I used to test this out was as follows:
void funky1() {
A a;
double ddd[50] = { 0.0 };
ddd[0] = 5.0; ddd[2] = 7.0;
a.SetPtr(&ddd[0]);
double *p = a;
bool bb = a == p;
long lll[50] = { 0 };
lll[0] = 5; lll[2] = 7;
long *q = a;
bb = a == q;
a.SetPtr(&lll[0]);
q = a;
bb = a == q;
}
I stepped through this with the debugger, Visual Studio 2013, and it looked like it worked like a champ.
I guess this answer is the most elegant.
Anyway, you can also let the class initializes your pointer as it follows:
class A {
void *_ptr;
public:
template<typename T>
void buffer(T **t) { *t = reinterpret_cast<T*>(_ptr); }
};
int main() {
A a;
double *b;
a.buffer(&b);
}
This way the type is deduced from the parameter list and you have not to explicitly specify it.

Passing default parameter to function C++

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

C++ lambda - capture member variable

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.

C++: Is it possible to use dynamic binding with a template parameter?

I have a template function which accepts a function-object ('functor') as a template parameter:
template <typename Func> int f (void) {
Func func;
return func ();
};
struct Functor {
virtual int operator () (void) = 0;
};
struct Functor0 : Functor {
int operator () (void) {
return 0;
}
};
struct Functor1 : Functor {
int operator () (void) {
return 1;
}
};
I want to avoid an if-else block like:
int a;
if (someCondition) {
a = f<Functor0> ();
}
else {
a = f<Functor1> ();
}
Is there a way to use something similar to dynamic binding, i.e something like:
a = f<Functor> (); // I know this line won't compile, it is just an example of what I need
and decide in runtime what (derived) type is passed as the template parameter?
Is there a way to use something similar to dynamic binding
No. This is fundamentally impossible. At some point in your code you need to have the case distinction. Of course, that doesn’t have to be written manually; you can use macros (or again templates) to generate the necessary code. But it needs to be there.
One way to avoid the check (if that is REALLY what you want to do), is to use an array - ..
Functor* fp[] = { new Functor0(), new Functor1() };
now - use someCondition as an index.
a = (*fp[someCondition])();
this relies simply on run-time polymorphism rather than the redundant template mechanism you are using... (btw. don't forget to cleanup!)
Of course, this is nasty and frankly redundant, the overhead of the if will be insignificant, but the clarity it adds to the code is significant...