I have some functions I'd like to benchmark. I would like be able to pass them into the benchmarking function. Previously I have passed a function pointer and reference to the object to the testing function like so
template<typename T>
void (T::*test_fn)(int, int), T& class_obj, )
At the moment I have this
#include <iostream>
#include <functional>
using namespace std::placeholders;
class aClass
{
public:
void test(int a, int b)
{
std::cout << "aClass fn : " << a + b << "\n";
}
};
class bClass
{
public:
void test(int a, int b)
{
std::cout << "bClass fn : " << a * b << "\n";
}
};
// Here I want to perform some tests on the member function
// passed in
class testing
{
public:
template<typename T>
void test_me(T&& fn, int one, int two)
{
fn(one, two);
}
};
int main()
{
aClass a;
bClass b;
auto fn_test1 = std::bind(&aClass::test, a, _1, _2);
auto fn_test2 = std::bind(&bClass::test, b, _1, _2);
testing test;
test.test_me(fn_test1, 1, 2);
test.test_me(fn_test2, 1, 2);
}
Is there a way I can do this using a lambda instead?
I know I can do this using std::bind but can I do this using a lambda and not have to do it each time for each member function I want to test (as below)?
The test_me function can take any callable object. Including lambdas. No modifications needed.
Something like
test.test_me([a](int one, int two) { a.test(one, two); }, 1, 2);
Related
It is well known that you cannot create a reference to a member function in C++ [source].
For those that don't know. The issue come when you want to do something similar to
class A
{
public:
void Add(int a, int b)
{
std::cout << "Sum is " << a + b << std::endl;
}
void CallAdd(int a, int b, void (*func)(int, int))
{
func(a, b);
}
};
and then call Add through CallAdd:
A a;
a.Add(3, 7); // This works fine
a.CallAdd(3, 7, &a.CallAdd); //This does not compile
The error is
error: cannot create a non-constant pointer to member function
a.CallAdd(3, 7, &a.CallAdd);
Which would not occur if it wiere outside a class.
There is a work around using std::function/lambda. Like this:
class A
{
public:
function<void(int, int)> AddFunc = [](int a, int b)
{
std::cout << "Sum is " << a + b << std::endl;
};
void CallAdd(int a, int b, std::function<void(int, int)> &func)
{
func(a, b);
};
};
int main()
{
A a;
a.CallAdd(3, 7, a.AddFunc);
}
This works fine but the problem is that computation time increases a lot (obviously this is just a minimal reproducible example) compared to simply calling the function.
Is there a way to increase computation speed or is this the best one can do?
For context, I have an algorithm to integrate functions, and I want to change integrands at will so the integrand must be a function parameter.
Pass the function object (or lambda) to a templated member function as follows:
#include <concepts>
#include <iostream>
inline auto myAddFunc = [](int a, int b) {
std::cout << "Sum is " << a + b << std::endl;
};
class A
{
public:
template <std::regular_invocable<int,int> Func>
void CallFunc(int a, int b, Func func)
{
func(a, b);
};
};
int main()
{
A a;
auto mySubFunc = [](int a, int b) {
std::cout << "Difference is " << a - b << std::endl;
};
a.CallFunc(3, 7, myAddFunc);
a.CallFunc(7, 3, mySubFunc);
}
If I have a class that needs to call a parent class method with a class method as parameter I can do it with std::function + std::bind as shown below:
class A {
void complexMethod(std::function<void()> variableMethod) {
// other stuff ...
variableMethod();
// some other stuff..
}
}
class B : public A {
void myWay() {
// this and that
}
void otherWay() {
// other and different
}
void doingSomething() {
// Preparing to do something complex.
complexMethod(std::bind(&B::myWay, this));
}
void doingAnotherThing() {
// Different preparation to do some other complex thing.
complexMethod(std::bind(&B::otherWay, this));
}
}
How would I need to change the above code to implement the same thing using templates instead of std::function + std::bind?
And how about lambdas instead of std::function + std::bind? I still want to call B:myWay() and B::otherWay() but using lambdas. I don't want to substitute B:myWay() and B::otherWay() with lambdas.
Is there any implementation technique (one of the above or some other) were I would be able to make variableMethod return type and parameters explicit? How would I do it? Let's say the signature of variableMethod is:
bool variableMethod(int a, double b);
Which technique is recommended? Why (speed, flexibility, readility...)?
Template + lambda solution:
struct A
{
template <typename F>
void runA(F func)
{
cout << 1 << endl;
func();
cout << 3 << endl;
}
};
struct B : A
{
int number = 2;
void runnable() { cout << number << endl; }
void runB()
{
cout << 0 << endl;
runA([this]() { runnable(); });
cout << 4 << endl;
}
};
int main()
{
B variable;
variable.runB();
}
In order to take a function as template parameter, just take in a template type of that function like above. lambdas can be used instead of bind to make things easier (this is passed to lambda captures list).
Explicitly declaring the arguments:
void run_func(std::function<bool(int, double)> func)
{
bool b = func(10, 10.01);
}
std::function allows you to define your arguement and return types like above.
How would I need to change the above code to implement the same thing
using templates instead of std::function + std::bind?
And how about lambdas instead of std::function + std::bind? I
still want to call B:myWay() and B::otherWay() but using lambdas.
I don't want to substitute B:myWay() and B::otherWay() with
lambdas.
You can use a lambda, yes.
Something like [this]() { return myWay(); } that:
captures this, and
calls a method of the current object.
[Demo]
#include <iostream> // cout
class A {
protected:
template <typename F>
void complexMethod(F&& f) { f(); }
};
class B : public A {
void myWay() { std::cout << "myWay\n"; }
void otherWay() { std::cout << "otherWay\n"; }
public:
void doingSomething() {
complexMethod([this]() { return myWay(); });
}
void doingAnotherThing() {
complexMethod([this]() { return otherWay(); });
}
};
int main() {
B b{};
b.doingSomething();
b.doingAnotherThing();
}
// Outputs:
//
// myWay
// otherWay
Is there any implementation technique (one of the above or some other)
were I would be able to make variableMethod return type and
parameters explicit? How would I do it?
You could use const std::function<bool(int,double)>& f as the parameter receiving a function for complexMethod. And still pass a lambda. Notice though lambdas are now receiving (int i, double d) (it could be (auto i, auto d) as well).
[Demo]
#include <functional> // function
#include <ios> // boolalpha
#include <iostream> // cout
class A {
protected:
bool complexMethod(const std::function<bool(int,double)>& f, int i, double d)
{ return f(i, d); }
};
class B : public A {
bool myWay(int a, double b) { return a < static_cast<int>(b); }
bool otherWay(int a, double b) { return a*a < static_cast<int>(b); }
public:
bool doingSomething(int a, double b) {
return complexMethod([this](int i, double d) {
return myWay(i, d); }, a, b);
}
bool doingAnotherThing(int a, double b) {
return complexMethod([this](auto i, auto d) {
return otherWay(i, d); }, a, b);
}
};
int main() {
B b{};
std::cout << std::boolalpha << b.doingSomething(3, 5.5) << "\n";
std::cout << std::boolalpha << b.doingAnotherThing(3, 5.5) << "\n";
}
// Outputs:
//
// true
// false
Notice also the same could be accomplished with templates, although you wouldn't be making the signature explicit.
[Demo]
#include <functional> // function
#include <ios> // boolalpha
#include <iostream> // cout
class A {
protected:
template <typename F, typename... Args>
auto complexMethod(F&& f, Args&&... args) -> decltype(f(args...))
{ return f(args...); }
};
class B : public A {
bool myWay(int a, double b) { return a < static_cast<int>(b); }
bool otherWay(int a, double b) { return a*a < static_cast<int>(b); }
public:
bool doingSomething(int a, double b) {
return complexMethod([this](auto i, auto d) {
return myWay(i, d); }, a, b);
}
bool doingAnotherThing(int a, double b) {
return complexMethod([this](auto i, auto d) {
return otherWay(i, d); }, a, b);
}
};
int main() {
B b{};
std::cout << std::boolalpha << b.doingSomething(3, 5.5) << "\n";
std::cout << std::boolalpha << b.doingAnotherThing(3, 5.5) << "\n";
}
// Outputs:
//
// true
// false
Which technique is recommended? Why (speed, flexibility,
readility...)?
Item 34 of Scott Meyer's Effective Modern C++ book is titled Prefer lambdas to std::bind. It ends with a summary saying: Lambdas are more readable, more expressive, and may be more efficient than using std::bind. However, it also mentions a case when std::bind may be useful over lambdas.
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
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
I am new to template and have a bit of problem using them.
I am posting the code below which I am not able to code for.
Need help in how to do this piece
I need someething like a function pointer being passed as a template argument to the tester class and the TClass instance being passed as the parameter to the constructor. In the constructor the function pointer will be used to bind the testFunc to a member variable of the tester class which is a function pointer. Then while the tester class is destroyed the testFunc will be called.
No able to resolve the type deduction for the template
#include <iostream>
using namespace std;
template< class TClass, TClass::*fptr>
class tester
{
public:
tester(TClass & testObj, ...) //... refer to the arguments of the test function which is binded
{
//bind the function to member fptr variable
}
~tester()
{
//call the function which was binded here
}
private:
(TClass::*fp)(...) fp_t;
};
class Specimen
{
public:
int testFunc(int a, float b)
{
//do something
return 0;
}
}
int main()
{
typedef int (Specimen::*fptr)(int,float);
Specimen sObj;
{
tester<fptr> myTestObj(sObj, 10 , 1.1);
}
return 0
}
using C++11 std::bind:
#include <functional>
#include <iostream>
class Specimen
{
public:
int testFunc(int a, float b)
{
std::cout << "a=" << a << " b=" << b <<std::endl;
return 0;
}
};
int main()
{
Specimen sObj;
auto test = std::bind(&Specimen::testFunc, &sObj, 10, 1.1);
test();
}
Check the documentation.
I mixed std::function and std::bind to get close to your problem:
template<typename F>
class tester
{
function<F> func;
public:
template <typename H, typename... Args>
tester(H &&f, Args&&... args) : func(bind(f, args...))
{
}
~tester()
{
func();
}
};
class Specimen
{
public:
int testFunc(int a, float b)
{
return a + b;
}
};
int main()
{
Specimen sObj;
tester<int()> myTestObj(&Specimen::testFunc, &sObj, 10 , 1.1);
}
Live code