Can I do something like this?
template<function_pointer_type pointer_name> struct structure1{
//here I call pointer_name(0)
};
void* function1 = [&](int a) {
return a * a;
}
structure1<function1> b;
I tried but it never compiled.
So, what's wrong with the code?
function1 is not constant expression so it cannot be used as template argument.
The lambda is not convertible to function pointer because it has a non-empty capture list.
Instead of function pointer, I suggest using a template parameter of function object, or std::function.
Function object:
template <class FunctionObject>
class A
{
private:
FunctionObject fun;
public:
A(FunctionObject f) : fun(f) {}
void f() { cout << fun(5) << endl; }
};
template <class FunctionObject>
A<FunctionObject> make_A(FunctionObject f)
{
return A<FunctionObject>(f);
}
std::function:
template <class FunctionType>
struct B
{
std::function<FunctionType> fun;
};
The usage:
void usage()
{
auto a = make_A([](int a) {return a*a; });
a.f();
B<int(int)> b;
b.fun = [&](int a) {return a*a; };
cout << b.fun(10) << endl;
}
To make this as absolutely similar to your original question as possible (using a lambda and a templated structure and so on):
#include <iostream>
template<typename F>
struct structure1 {
structure1(F x) : f(x) {}
int operator() (int a) { return f(a); };
F f;
};
int(*function1)(int) = [&](int a) {
return a * a;
};
int main() {
structure1< int(*)(int) > x(function1);
std::cout << x(4) << std::endl;
return 0;
}
I compiled and tested this with g++ -std=c++11 test.cpp
Related
Looking at this answer I can see how to call a pointer to a member function by explicitly passing in this. However, what if I want the function passed in to be a member of the current object and to use the implicit this.
I've written this, which seems to work, but is it valid code, and is there a better way (C++14 or below) avoiding the dynamic_cast<>? Source on onlinegdb.com
#include <iostream>
class Base
{
public:
// From https://stackoverflow.com/a/9779391/1270789
template<typename T, typename R>
R proxycall(T *obj, R (T::*mf)(int))
{
return (obj->*mf)(42);
}
// My attempt
template<typename T, typename R>
R proxycall(R (T::*mf)(int))
{
return ((dynamic_cast<T *>(this))->*mf)(42);
}
virtual ~Base() {}
};
class Foo: public Base
{
public:
int doFoo(int x) { std::cout << "doing foo\n"; return x / 2; }
int doCall() { return proxycall(this, &Foo::doFoo); } // OK
int doNoThisCall() { return proxycall(&Foo::doFoo); } // Is this OK?
};
int main()
{
Foo foo;
std::cout << foo.doCall() << '\n';
std::cout << foo.doNoThisCall() << '\n';
return 0;
}
Consider this pseudo-snippet:
class SomeClass
{
public:
SomeClass()
{
if(true)
{
fooCall = [](auto a){ cout << a.sayHello(); };
}
else
{
fooCall = [](auto b){ cout << b.sayHello(); };
}
}
private:
template<typename T>
std::function<void(T)> fooCall;
};
What I want is a class member fooCall which stores a generic lambda, which in turn is assigned in the constructor.
The compiler complains that fooCall cannot be a templated data member.
Is there any simple solution on how i can store generic lambdas in a class?
There is no way you'll be able to choose between two generic lambdas at run-time, as you don't have a concrete signature to type-erase.
If you can make the decision at compile-time, you can templatize the class itself:
template <typename F>
class SomeClass
{
private:
F fooCall;
public:
SomeClass(F&& f) : fooCall{std::move(f)} { }
};
You can then create an helper function to deduce F:
auto makeSomeClassImpl(std::true_type)
{
auto l = [](auto a){ cout << a.sayHello(); };
return SomeClass<decltype(l)>{std::move(l)};
}
auto makeSomeClassImpl(std::false_type)
{
auto l = [](auto b){ cout << b.sayHello(); };
return SomeClass<decltype(l)>{std::move(l)};
}
template <bool B>
auto makeSomeClass()
{
return makeSomeClassImpl(std::bool_constant<B>{});
}
I was not able to store std::function<> as a generic lambda in the class directly as a member. What I was able to do was to specifically use one within the class's constructor. I'm not 100% sure if this is what the OP was trying to achieve but this is what I was able to compile, build & run with what I'm suspecting the OP was aiming for by the code they provided.
template<class>
class test {
public: // While testing I changed this to public access...
// Could not get object below to compile, build & run
/*template<class U = T>
static std::function<void(U)> fooCall;*/
public:
test();
};
template<class T>
test<T>::test() {
// This would not compile, build & run
// fooCall<T> = []( T t ) { std::cout << t.sayHello(); };
// Removed the variable within the class as a member and moved it here
// to local scope of the class's constructor
std::function<void(T)> fooCall = []( auto a ) { std::cout << a.sayHello(); };
T t; // created an instance of <Type T>
fooCall(t); // passed t into fooCall's constructor to invoke the call.
}
struct A {
std::string sayHello() { return "A say's Hello!\n"; }
};
struct B {
std::string sayHello() { return "B say's Hello!\n"; }
};
int main() {
// could not instantiate an object of SomeClass<T> with a member of
// a std::function<> type that is stored by a type of a generic lambda.
/*SomeClass<A> someA;
SomeClass<B> someB;
someA.foo();
someB.foo();*/
// Simply just used the object's constructors to invoke the locally stored lambda within the class's constructor.
test<A> a;
test<B> b;
std::cout << "\nPress any key & enter to quit." << std::endl;
char c;
std::cin >> c;
return 0;
}
With the appropriate headers the above as is should compile, build & run giving the output below (At least in MSVS 2017 on Windows 7 64bit did); I left comments where I ran into errors and tried multiple different techniques to achieve a working example, errors occurred as others suggested and I found even more while working with the above code. What I was able to compile, build and run came down to this simple bit of code here without the comments. I also added another simple class to show it will work with any type:
template<class>
class test {
public:
test();
};
template<class T>
test<T>::test() {
std::function<void( T )> fooCall = []( auto a ) { std::cout << a.sayHello(); };
T t;
fooCall( t );
}
struct A {
std::string sayHello() { return "A say's Hello!\n"; }
};
struct B {
std::string sayHello() { return "B say's Hello!\n"; }
};
struct C {
int sayHello() { return 100; }
};
int main() {
test<A> testA;
test<B> testB;
test<C> testC;
std::cout << "\nPress any key & enter to quit." << std::endl;
char c;
std::cin >> c;
return 0;
}
Output:
A say's Hello!
B say's Hello!
100
Press any key & enter to quit
I don't know if this will help the OP directly or indirectly or not but if it does or even if it doesn't it is still something that they may come back to and build off of.
you can simply use a template class or...
If you can get away with using c++17, you could make fooCall's type std::function<void(const std::any&)> and make a small wrapper for executing it.
method 1 : simply use a template class (C++14).
method 2 : seems to mimic the pseudo code exactly as the OP intended (C++17).
method 3 : is a bit simpler and easier to use than method 2 (C++17).
method 4 : allows us to change the value of fooCall (C++17).
required headers and test structures for the demo :
#include <any> //not required for method 1
#include <string>
#include <utility>
#include <iostream>
#include <functional>
struct typeA {
constexpr const char * sayHello() const { return "Hello from A\n"; }
};
struct typeB {
const std::string sayHello() const { return std::string(std::move("Hello from B\n")); }
};
method 1 :
template <typename T>
class C {
const std::function<void(const T&)> fooCall;
public:
C(): fooCall(std::move([](const T &a) { std::cout << a.sayHello(); })){}
void execFooCall(const T &arg) {
fooCall(arg);
}
};
int main (void) {
typeA A;
typeB B;
C<typeA> c1;
C<typeB> c2;
c1.execFooCall(A);
c2.execFooCall(B);
return 0;
}
method 2 :
bool is_true = true;
class C {
std::function<void(const std::any&)> fooCall;
public:
C() {
if (is_true)
fooCall = [](const std::any &a) { std::cout << std::any_cast<typeA>(a).sayHello(); };
else
fooCall = [](const std::any &a) { std::cout << std::any_cast<typeB>(a).sayHello(); };
}
template <typename T>
void execFooCall(const T &arg) {
fooCall(std::make_any<const T&>(arg));
}
};
int main (void) {
typeA A;
typeB B;
C c1;
is_true = false;
C c2;
c1.execFooCall(A);
c2.execFooCall(B);
return 0;
}
method 3 :
/*Note that this very closely resembles method 1. However, we're going to
build off of this method for method 4 using std::any*/
template <typename T>
class C {
const std::function<void(const std::any&)> fooCall;
public:
C() : fooCall(std::move([](const std::any &a) { std::cout << std::any_cast<T>(a).sayHello(); })) {}
void execFooCall(const T &arg) {
fooCall(std::make_any<const T&>(arg));
}
};
int main (void) {
typeA A;
typeB B;
C<typeA> c1;
C<typeB> c2;
c1.execFooCall(A);
c2.execFooCall(B);
return 0;
}
method 4 :
/*by setting fooCall outside of the constructor we can make C a regular class
instead of a templated one, this also complies with the rule of zero.
Now, we can change the value of fooCall whenever we want.
This will also allow us to do things like create a container that stores
a vector or map of functions that each take different parameter types*/
class C {
std::function<void(const std::any&)> fooCall; //could easily be replaced by a vector or map
public:
/*could easily adapt this to take a function as a parameter so we can change
the entire body of the function*/
template<typename T>
void setFooCall() {
fooCall = [](const std::any &a) { std::cout << std::any_cast<T>(a).sayHello(); };
}
template <typename T>
void execFooCall(const T &arg) {
fooCall(std::make_any<const T&>(arg));
}
};
int main (void) {
typeA A;
typeB B;
C c;
c.setFooCall<typeA>;
c.execFooCall(A);
c.setFooCall<typeB>;
c.execFooCall(B);
return 0;
}
Output from Any method
Hello from A
Hello from B
In C++, we can pass a function/functor to a function like so:
template <typename F>
void doOperation(int a, int b, F f){
std::cout << "Result: " << f(a,b) << std::endl;
}
we can then use both functions and functors:
int add(const int &a, const int &b){ return a+b; }
struct subtract(){
void operator() (const int &a, const int &b) { return a-b; }
};
and use it in the following manner:
doOperation(1,2,add);
doOperation(5,2,subtract());
My question is, can I do something similar with a class and pass a function as an argument to a class, store it and use it later? E.g.
template <typename F>
class doOperation{
public:
doOperation(int &a, int &b, F f) : a(a), b(b), f(f) {};
void setOperands(int &a, int &b) { this->a = a; this->b = b };
void performCalculation(){
std::cout << "Result: " << f(a,b) << std::endl;
}
private:
int a,b;
F f;
}
So that we may assign it a function once and then later use it:
doOperation summing(1,2,add);
summing.setOperands(2,3);
summing.performCalculation();
doOperation subtraction(7,3,subtract());
subtraction.performCalculation();
If my examples are valid, I would appreciate the explanation for the mechanics here as I seem to be getting a bit lost. In case I missed something, I am looking for hints on whether this can be achieved.
Lastly, how would I then use such a class doOperation in other functions and classes. For example, would defining something like this inside a member function require me to template the new class, its member function, and how would it be declared and used:
class higherFunctionality{
public:
higherFunctionality() {...}
void coolThings(){
doOperation *myOperation = operationFactory( ... );
myOperation->setOperands(4,5);
myOperation->performCalculation();
}
};
Yes, but you have to supply the type when you instantiate template classes. The usual way to deal with this is to create a helper function:
template < typename Fun > struct operation_class
{
operation_class(Fun f) : fun{f} {}
Fun fun;
};
template < typename Fun >
operation_class<Fun> operation(Fun fun) { return operation_class<Fun>{fun}; }
int main()
{
auto op0 = operation(some_fun);
auto op1 = operation(some_functor{});
}
Frankly though, you are better off just using lambda:
auto op0 = [a,b]() { return sum(a,b); };
auto op1 = [a,b]() { return subtract{a,b}(); }
// C++17:
auto op2 = [op=subtract{a,b}] { return op(); };
I am looking for a way to decorate functions or lambdas in C++. The goal is to do something before and after the function call. As I've seen the closest thing to use is std::function but it needs to have the types of its arguments.
class FunctionDecorator
{
public:
FunctionDecorator( std::function func )
: m_func( func )
void operator()()
{
// do some stuff prior to function call
m_func();
// do stuff after function call
}
private:
std::function m_func;
};
It would be great if by template type could be used in std::function and it could deduce it somehow when i pass pointer to a function or a result from std::bind.
Is such thing possible in C++.
Hmm. I may or may not have gone overkill.
#include <type_traits>
#include <utility>
#include <iostream>
template <class T>
struct RetWrapper {
template <class Tfunc, class... Targs>
RetWrapper(Tfunc &&func, Targs &&... args)
: val(std::forward<Tfunc>(func)(std::forward<Targs>(args)...)) {}
T &&value() { return static_cast<T &&>(val); }
private:
T val;
};
template <>
struct RetWrapper<void> {
template <class Tfunc, class... Targs>
RetWrapper(Tfunc &&func, Targs &&... args) {
std::forward<Tfunc>(func)(std::forward<Targs>(args)...);
}
void value() {}
};
template <class Tfunc, class Tbefore, class Tafter>
auto decorate(Tfunc &&func, Tbefore &&before, Tafter &&after) {
return [
func = std::forward<Tfunc>(func),
before = std::forward<Tbefore>(before),
after = std::forward<Tafter>(after)
] (auto &&... args) -> decltype(auto) {
before(std::forward<decltype(args)>(args)...);
RetWrapper<std::result_of_t<Tfunc(decltype(args)...)>> ret(
func, std::forward<decltype(args)>(args)...
);
after(std::forward<decltype(args)>(args)...);
return ret.value();
};
}
/*
* Tests
*/
float test1(float a, float b) {
std::cout << "Inside test1\n";
return a * b;
}
void test2() {
std::cout << "Inside test2\n";
}
int i = 0;
int &test3() {
return i;
}
int main() {
auto test1Deco = decorate(
test1,
[] (float a, float b) {
std::cout << "Calling test1 with " << a << " and " << b << '\n';
},
[] (float a, float b) {
std::cout << "Called test1 with " << a << " and " << b << '\n';
}
);
float c = test1Deco(3.5f, 5.1f);
std::cout << "Yields " << c << '\n';
auto test2Deco = decorate(
test2,
[] () {
std::cout << "Calling test2\n";
},
[] () {
std::cout << "Called test2\n";
}
);
test2Deco();
auto test3Deco = decorate(
test3,
[] () {
std::cout << "Calling test3\n";
},
[] () {
std::cout << "Called test3\n";
}
);
auto &i2 = test3Deco();
i2 = 42;
std::cout << "Global i = " << i << '\n';
return 0;
}
Output :
Calling test1 with 3.5 and 5.1
Inside test1
Called test1 with 3.5 and 5.1
Yields 17.85
Calling test2
Inside test2
Called test2
Calling test3
Called test3
Global i = 42
Just go full template, without std::function:
template< typename Func >
class FunctionDecorator
{
public:
FunctionDecorator( Func func )
: m_func( std::move(func) )
{}
void operator()()
{
// do some stuff prior to function call
m_func();
// do stuff after function call
}
private:
Func m_func;
};
template< typename Func >
FunctionDecorator<Func> decorate(Func func) {
return FunctionDecorator<Func>(std::move(func));
}
[Note: edited a few hours after initial posting]
This perhaps isn't exactly what the OP was looking for, but it's still relevant and hopefully useful to others looking for answers.
Let's say you have a couple of functions that have slightly different signatures:
void foo1(int& x){ cout << "foo1(" << x << ")\n";}
void foo2(double& x){ cout << "foo2(" << x << ")\n";}
and you'd like to wrap a decorator around them both so as to standardise their signatures, e.g. turn them both into void (*)(int).
Then you could do the following:
template<typename Q, void (*foo_p)(Q&)>
void wrapped(int x){
Q v = 42.2 + x;
foo_p(v);
}
int main(){
using foo_t = void (*)(int); // we coerce foo1 and foo2 into this type
foo_t k_int = wrapped<int, foo1>;
foo_t k_double = wrapped<double, foo2>;
k_int(-1); //cout: foo1(41)
k_double(-1); //cout: foo2(41.2)
return 0;
}
Using the example main I've given here, clang inlines the whole thing, which is a good sign but not quite what we wanted to check. If you make the example a bit more complex (see live here) you can see that it does indeed inline everything within each wrapper, i.e. foo1 and foo2 don't exist in standalone form, only in wrapped form.
Originally, I use a lambda in addition to the wrapped<...> template (making use of the fact that lambdas with no-capture can be converted to function pointers) but then I realized that the extra wrapping was redundant in this case.
This method should work for passing anything known at run time, which could even include a pointer to a mutable global (although that's getting pretty messy).
#include <iostream>
#include <string>
using namespace std;
template <typename TResult, typename TParams>
class CClassGenerique
{
typedef TResult (*uneFonction) (TParams);
public :
CClassGenerique (uneFonction f){ m_function = f; }
void operator () (TParams t) { m_function (t); }
private :
uneFonction m_function;
};
template <typename TResult, typename TParams>
TResult BasicFunction (TParams p)
{
TResult t=0;
std::cout<<" Value = " << p <<endl;
return t;
}
int main (int argc, char* argv[])
{
CClassGenerique<int, int> c1 (BasicFunction<int, int>);
CClassGenerique<int, char*> c2 (BasicFunction<int, char*>);
CClassGenerique<char*, char*> c3 (BasicFunction<char*, char*>);
c1(3);
c2("bonsoir");
c3("hello");
return 0;
}
Suppose we need to instantiate a function that calls some class method from inside non-trivial code.
#include <iostream>
class A
{
public:
int f() { return 1; }
int g() { return 2; }
};
template <class T, int (T::*method)()>
int func(T& x)
{
// some complex code here calling method()
return (x.*method)();
}
int main()
{
A a;
std::cout << func<A, &A::f>(a) << "\n"
<< func<A, &A::g>(a) << "\n";
return 0;
}
This code compiles and works fine. Now suppose that the two methods are actually const and non-const, like this:
class A
{
int val_;
public:
A() : val_(0) {}
int alloc() { return ++val_; }
int get() const { return val_; }
};
This time we can't use the same approach, because the member functions have different signatures due to const qualifier. Moving the problem to run time does not seem to solve anything, Is there a way to avoid rewriting func() as two functions in this situation?
Can you change passing method from template parameter to function parameter?
If yes, this works:
#include <iostream>
class A
{
public:
int f() { return 1; }
int g() const { return 2; }
};
template <class T, class F>
int func(F method, T& x)
{
// some complex code here calling method()
return (x.*method)();
}
int main()
{
A a;
std::cout << func(&A::f, a) << "\n"
<< func(&A::g, a) << "\n";
return 0;
}