I wish to create many functions with the same parameters, for example:
const int add(const int a, const int b) {
return (a + b);
}
decltype(add) subtract {
return (a - b);
}
/* many more functions */
The purpose being that I am able to easily change the types of the parameters once to change all of the functions. I know that this is possible with macros as so:
#define INT_OPERATION(name) const int name (const int a, const int b)
INT_OPERATION(add) { return (a + b); }
INT_OPERATION(subtract) {return (a - b); }
However, I dislike the use of macros. Is there a safer way of doing this?
A function signature cannot be typedefed. Only a function's type. So it's valid to say :
typedef int INT_OPERATION(int a, int b);
and then forward declare a function having this type :
INT_OPERATION Add;
but when it comes to defining the function you'd have to specify arguments, so the follwing is invalid
INT_OPERATION Add { /* No can do */ }
(as soon as you place a set of () after Add you'll be declaring a function returning a plain function which is not valid C++)
On generic types
The same procedure has similar limitations when using the tools for generic programming. You can declare the following typedef :
template<typename T>
using INT_OPERATION = const T(T const, T const);
And then use it for a function (forward) declaration
INT_OPERATION<int> add;
int main() {
std::cout << add(1, 2) << std::endl;
return 0;
}
but when it comes to defining it, you'd have to be mandane
const int add(int const a, int const b) {
return a + b;
}
Demo
Maybe something like that:
#include <iostream>
#include <functional>
typedef std::function<int(int, int)> IntFunction;
IntFunction add = [](int a, int b) {return a + b;};
IntFunction substract = [](int a, int b) {return a - b;};
int main(int, char**) {
std::cout << add(1, 2) << std::endl;
std::cout << substract(1, 2) << std::endl;
return 0;
}
Still boilerplate code, but worth a try ;)
If these were member functions you could declare their common type (typedef const int Fn(int, int)), declare the member functions inside the class using that type:
Fn add, subtract;
Then you define them outside the class in the normal way. Doesn't save boilerplate, but at least means it won't compile if you make a typo in the definitions.
Alternatively for non member functions see the question I linked to which has some clever ways to define function pointers rather than functions.
If your primary concern is being able to "easily change the types of the parameters", it's straightforward to write them as templates so that you never have to change the types of the parameters:
template <typename T1, typename T2>
auto add (const T1 &a, const T2 &b) -> decltype(a + b) {
return (a + b);
}
This also handles cases where a and b are not of the same type, or where a + b is not the same type as a or b.
Related
I have come across this code snippet and have no idea what it means:
#include <iostream>
int main(){
using test = int(int a, int b);
return 0;
}
I can guess test can be used instead of int(int a, int b), but what does int(int a, int b) even mean? is it a function? How can it be used?
int(int a, int b) is a function declaration that has two parameters of the type int and the return type also int.
You can use this alias declaration for example as a member function declarations of a class or using it in a parameter declaration.
It's an alias for a function signature.
A more complete usage is to declare a pointer or reference to a function
int foo(int, int);
int main()
{
using test = int(int a, int b); // identifiers a and b are optional
test *fp = &foo;
test *fp2 = foo; // since the name of function is implicitly converted to a pointer
test &fr = foo;
test foo; // another declaration of foo, local to the function
fp(1,2); // will call foo(1,2)
fp2(3,4); // will call foo(3,4)
fr(5,6); // will call foo(5,6)
foo(7,8);
}
Just to give another use option of this line, with lambda expressions:
int main() {
using test = int(int, int);
test le = [](int a, int b) -> int {
return a + b;
}
return 0;
}
One point that you have to keep in mind about this use of test, there are probably more efficient ways to declare a function signature, like auto in lambda expressions case, template in case of passing function as argument to another function, etc.
This way came all the way from pure C programming, with the using twist. I won't recommend of choosing this way, but for general understanding it is always good to know more than the correct ways.
I am trying to implement a member function in a C++ class which has an auto argument (a lambda) and an int argument with a default value. Something like this:
class Base {
public:
int add_one(auto fobj, int b=3);
};
int Base::add_one(auto add_fcn, int b) {
return add_fcn(1, b);
}
However, a simple test like this fails to compile:
#include <iostream>
class Base {
public:
int add_one(auto fobj, int b=3);
};
int Base::add_one(auto add_fcn, int b) {
return add_fcn(1, b);
}
int main() {
int ans;
auto add_fcn = [](int a, int b) -> int {return a + b;};
Base obj;
ans = obj.add_one(add_fcn);
std::cout << ans << "\n";
return 0;
}
The error the compiler (MinGW 7.2.0, flags: -std=c++14) gives me is the following:
error: call to 'int Base::add_one(auto:2, int) [with auto:1 = main()::<lambda(int, int)>]' uses the default argument for parameter 2, which is not yet defined
I sincerely do not understand the error. Can someone please explain me the reason of this error and how it can be fixed? Thank you in advance.
auto parameters is a gcc extension. It means that it is not a standard compliant way to solve the problem.
I am not sure what is the exact reason for the error above, but you might achieve the same effect with template member function which works well:
class Base {
public:
template<typename F>
int add_one(F fobj, int b = 3);
};
template<typename F>
int Base::add_one(F add_fcn, int b) {
return add_fcn(1, b);
}
Wandbox example
Another possible way is to use std::function (which implies some performance overhead though):
class Base {
public:
int add_one(std::function<int(int, int)> fobj, int b = 3);
};
int Base::add_one(std::function<int(int, int)> add_fcn, int b) {
return add_fcn(1, b);
}
Wandbox example
Finally, you could make use of pointers to functions, but it is too C way...
If you'd like to expand your knowledge on passing functions to functions, this article by Vittorio Romeo gives an excellent explanation + some benchmarks.
There is a class C with methods foo, boo, boo_and_foo and foo_and_boo. Each method takes i,j,k and l clock cycles respectively, where i < j, k < i+j and l < i+j.
class C
{
public:
int foo() {...}
int boo() {...}
int boo_and_foo() {...}
int foo_and_boo() {...} };
In code one might write:
C c;
...
int i = c.foo() + c.boo();
But it would be better to have:
int i = c.foo_and_boo();
What changes or techniques could one make to the definition of C, that would allow similar syntax of the original usage, but instead have the compiler generate the latter.
Note that foo and boo are not commutative.
Idea 1 Thanks the comments!
I was thinking creater a cHelper class, and a cOps class with string member ops, so that after have cHelper ch;, we can write int i = ch.foo() + ch.boo();
ch.foo() does nothing but returns: cOps("foo")
ch.boo() also only returns: cOps("boo")
overload "+" operator for cOps class so that cOps("foo") + cOps("boo") actually returns cOps("foo,boo")
overload the int type conversion operator of cOps so that int i = cOps("foo") ; actually calls c.foo(); while int i = cOps("foo,boo") ; actually calls c.foo_and_boo();
A bit ugly ....
The objective sounds rather similar to what Todd Veldhuizen pioneered many moons ago for Blitz++: aggregating operations effectively into an expression tree to effectively change the order of computations. In the case of Blitz++ it was done for matrix operations. The technique is known as Expression Templates.
The overall idea would not be to aggregate a string and its operations, though, but rather to encode the necessary operations in the type returned. Similar to what is described in the question the evaluation of the expression is delayed until they are needed. By using specializations for specific operations the compiler would be made to choose the appropriate combations. It could look somewhat like this:
#include <iostream>
namespace C_ops { struct C_tag {}; }
struct C_foo;
struct C_bar;
class C: C_ops::C_tag {
int value;
public:
explicit C(int value): value(value) {}
C_foo foo() const;
C_bar bar() const;
int actual_foo() const {
std::cout << "compute foo(" << value << ")\n";
return value;
}
int actual_bar() const {
std::cout << "compute bar(" << value << ")\n";
return value;
}
int foo_and_bar(C const& r) const {
std::cout << "compute foo_and_bar(" << this->value << ", " << r.value << ")\n";
return this->value;
}
int bar_and_foo(C const& r) const {
std::cout << "compute bar_and_foo(" << this->value << ", " << r.value << ")\n";
return this->value;
}
};
struct C_foo: C_ops::C_tag {
C const& c;
C_foo(C const& c): c(c) {}
operator int() const { return c.actual_foo(); }
};
struct C_bar: C_ops::C_tag {
C const& c;
C_bar(C const& c): c(c) {}
operator int() const { return c.actual_bar(); }
};
C_foo C::foo() const { return C_foo(*this); }
C_bar C::bar() const { return C_bar(*this); }
template <typename L, typename R>
struct C_add;
template <>
struct C_add<C_foo, C_bar> {
C_foo l;
C_bar r;
C_add(C_foo const& l, C_bar const& r): l(l), r(r) {}
operator int() const { return l.c.foo_and_bar(r.c); }
};
template <>
struct C_add<C_bar, C_foo> {
C_bar l;
C_foo r;
C_add(C_bar const& l, C_foo const& r): l(l), r(r) {}
operator int() const { return l.c.bar_and_foo(r.c); }
};
// more specializations, e.g., to deal with C on the LHS
namespace C_ops {
template <typename L, typename R>
C_add<L, R> operator+(L const& l, R const& r) {
return C_add<L, R>(l, r);
}
}
template <typename... T> void use(T const&...) {}
int main()
{
C c0(0), c1(1);
int r0 = c0.foo();
int r1 = c0.bar();
int r2 = c0.foo() + c1.bar();
int r3 = c0.bar() + c1.foo();
std::cout << "done\n";
use(r0, r1, r2, r3); // make them used to not have them optimized away (for now)
}
With the setup above, the four expressions you mentioned would be covered. There are probably more specializations needed, e.g., to all c + c.foo(), c + c, etc. but the overall principle doesn't really change. You may want to protect actual_foo() and actual_bar() from being accessed and making the respective classes needing to call the friends.
The need for the extra namespace C_ops is merely to provide "catch-all" operators which hijack operator+() for all types, as long as they happen to be loooked up in this namespace. To do so, there is also a tag-type which has no other purpose than directing ADL (argument dependent look-up) to look into this namespace.
This is quite a cute technique which worked rather reliably with C++03: since the expressions are evaluated when the target type (in the above case int) is needed and C++03 didn't really allow for capturing the intermediate type while potentially involved temporary object were not around any more (the only was to catch the expression type in a deduced context would be when passing it to a function template) there were no life-time issues. With C++11 it is to capture the type of objects using auto which would capture the expression type, not evaluated result, there is probably some need to think properly about life-time of involved objects. The above example just used const objects but you'll probably need to be more careful and prevent certain temporary objects from being capture, primarily objects of type C. From your descriptions it isn't clear whether these would be expensive objects: the ideal solution would be to capture all objects by value but that may be too expensive.
This question already has answers here:
How do you pass a member function pointer?
(6 answers)
Closed 9 years ago.
I have a class
class A{
A(/*constructor arguments*/);
double MethA(double);
};
And I want to pass the method MethA in a function that takes a pointer to a function :
double function(double (*f)(double), double x){
return f(x);
}
So what I'm doing is to call
A a(/*constructor arguments*/);
function(a.MethA,1.0);
but it doesn't compile.
I'm pretty sure that this question is answered somewhere else, but I couldn't find where because I'm not sure that the terminology I use is correct. Am I trying to pass a pointer on a class method as a function argument ? Or, to pass a function pointer as a member of a class... I'm confused :-(
When you need to use a pointer to member function, you need to pass two separate things:
what member function to call and
what instance to call it on.
In C++, you can't combine them in one construct, like you want to:
A a;
bar(a.foo);
is not valid C++.
Instead, you have to do this:
A a;
bar(a, &A::foo)
And declare and implement bar() accordingly:
void bar(A &a, void (A::*method)()) {
a.*method();
}
See Arkadiy's answer if you want to see how to properly use member function pointers.
BUT
As requested in the comments: if the compiler you are using supports lambdas (some without full C++11 do). You can do something like the following, which looks more like the syntax you are attempting to use.
Your definition for function changes to something like:
template <typename F>
double function(F f, double x){
return f(x);
};
a function template that accepts a parameter that is callable with a double.
At your call-site you do this:
A a(/*constructor arguments*/);
function([&](double x){return a.MethA(x);},1.0);
That generates a function object in-place that is bound to your class instance a by reference.
The template can be made fully typesafe with some magic in <type_traits>, but as-is it will give you template spew if you pass something very wrong.
It has to be a static function!
#include <iostream>
#include <cassert>
class A {
public:
static double MethA(double x) { return 5 * x; }
};
typedef double (*ftype)(double);
double function(ftype f) {
assert(f != NULL);
return f(7);
}
int main(int, char**) {
// expect "35\n" on stdout
std::cout << function(A::MethA) << "\n";
}
It has to be static because you can't access any of A's variables without knowing which A object are you refering to! If you need A's non-static member variables, you need to pass a reference to an a into the static function:
#include <iostream>
#include <cassert>
class A {
double fX;
public:
A(double x) : fX(x) { }
double methB(double x) const { return fX * x; }
static double MethB(double x, const A& a) {
return a.methB(x);
}
};
typedef double (*ftype2)(double, const A&);
double function_with_context(ftype2 f, const A& a) {
assert(f != NULL);
return f(7, a);
}
int main(int, char**) {
A a(6);
// expect "42\n" on stdout
std::cout << function_with_context(A::MethB, a) << "\n";
}
But it's sometimes better to use inheritance and polymorphism to achieve this sort of interface:
#include <iostream>
class MyInterface {
public:
virtual double f(double x) const = 0;
};
class A : public MyInterface {
double fX;
public:
A(double x) : fX(x) { }
double f(double x) const {
return fX * x;
}
};
double function(const MyInterface& o) {
return o.f(7);
}
int main(int, char**) {
A a(6);
// expect "42\n" on stdout
std::cout << function(a) << "\n";
}
I suspect this is impossible, but thought I'd ask. Say I have a class with a method:
class A {
public:
void b(int c);
};
I can make a pointer to that member function:
void (A::*ptr)(int) = &A::b;
(someAInstance.*ptr)(123);
I can also abuse function pointers and make a pointer that takes the A argument directly (I don't know if this is safe, but it works on my machine):
void (*ptr2)(A*, int) = (void (*)(A*, int))&A::b;
(*ptr2)(&someAInstance, 123);
What I want is to somehow curry the A argument, and create a function pointer that just takes an int, but calls the A::b method on a particular A instance I've predefined. The A instance will stay constant for that particular function pointer, but there may be several function pointers all pointing to the same A::b method, but using different A instances. For example, I could make a separate wrapper function:
A* someConstantA = new A;
void wrapper(int c) {
someConstantA->b(c);
}
void (*ptr3)(int) = &wrapper;
Now I can use ptr3 without knowing which particular A it's dispatching the call to, but I had to define a special function to handle it. I need a way to make pointers for any number of A instances, so I can't hardcode it like that. Is this in any way possible?
Edit: Should've mentioned, I'm trapped in C++03 land, and also can't use Boost
Don't create a wrapper function, create a wrapper functor. This allows you to encapsulate whatever state you want to (e.g. an A*) in a callable object.
class A {
public:
void b(int c) {}
};
struct wrapper {
A* pA;
void (A::*pF)(int);
void operator()(int c) { (pA->*pF)(c); }
wrapper(A* pA, void(A::*pF)(int)) : pA(pA), pF(pF) {}
};
int main () {
A a1;
A a2;
wrapper w1(&a1, &A::b);
wrapper w2(&a2, &A::b);
w1(3);
w2(7);
}
If you have a sufficiently new compiler (e.g. gcc 4.2+), it should include TR1, where you could use std::tr1::bind:
#include <cstdio>
#include <tr1/functional>
class A {
public:
void b(int c) {
printf("%p, %d\n", (void*)this, c);
}
};
int main() {
A* a = new A;
std::tr1::function<void(int)> f =
std::tr1::bind(&A::b, a, std::tr1::placeholders::_1); // <--
f(4);
delete a;
return 0;
}
It is also doable in pure C++03 without TR1, but also much more messier:
std::binder1st<std::mem_fun1_t<void, A, int> > f =
std::bind1st(std::mem_fun(&A::b), a);
You could also write your own function objects.
Note that, in all the above cases, you need to be very careful about the lifetime of a since that is a bare pointer. With std::tr1::bind, you could at least wrap the pointer in a std::tr1::shared_ptr, so that it can live just as long as the function object.
std::tr1::shared_ptr<A> a (new A);
std::tr1::function<void(int)> f =
std::tr1::bind(&A::b, a, std::tr1::placeholders::_1);
If you are using C++11, you might use a lambda (untested code):
template<typename T, typename A>
std::function<void(A)> curry(T& object, void (T::*ptr)(A))
{
return [](A a) { (object.*ptr)(std::forward<A>(a)); }
}
I'd be using Boost::bind for this.
Basically:
class A
{
int myMethod(int x)
{
return x*x;
}
};
int main(int argc, char* argv[])
{
A test();
auto callable = boost::bind(&A::myMethod, &A, _1);
// These two lines are equivalent:
cout << "object with 5 is: " << test.myMethod(5) << endl;
cout << "callable with 5 is: " << callable(5) << endl;
return 0;
}
I think that should work. I'm also using auto in here to deduce the type returned by boost::bind() at compile-time, which your compiler may or may not support. See this other question at stackoverflow for an explanation of the return type of bind.
Boost supports back to Visual Studio 2003 (I think) and this all this will work there, though you'll be using BOOST_AUTO I think. See the other question already linked for an explanation.
What you want to do is not possible.
To see why, assume that it is possible - the function pointer must point to a function somewhere in your executable or one of its libraries, so it must point to a function that knows which instance of A to call, much like your wrapper function. Because the instance of A is not known until runtime, you'd have to create those functions at runtime, which isn't possible.
What you're trying to do is possible in C++03, as long as you're happy to pass around a function object rather than a function pointer.
As others have already given solutions with C++11 lambdas, TR1 and boost (all of which are prettier than the below), but you mentioned you can't use C++11, I'll contribute one in pure C++03:
int main()
{
void (A::*ptr)(int) = &A::b;
A someAInstance;
std::binder1st<std::mem_fun1_t<void,A,int> > fnObj =
std::bind1st(std::mem_fun(ptr), &someAInstance);
fnObj(321);
};
I've worked something out with a template Delegate class.
// T is class, R is type of return value, P is type of function parameter
template <class T, class R, class P> class Delegate
{
typedef R (T::*DelegateFn)(P);
private:
DelegateFn func;
public:
Delegate(DelegateFn func)
{
this->func = func;
}
R Invoke(T * object, P v)
{
return ((object)->*(func))(v);
}
};
class A {
private:
int factor;
public:
A(int f) { factor = f; }
int B(int v) { return v * factor; }
};
int _tmain(int argc, _TCHAR* argv[])
{
A * a1 = new A(2);
A * a2 = new A(3);
Delegate<A, int, int> mydelegate(&A::B);
// Invoke a1->B
printf("Result: %d\n", mydelegate.Invoke(a1, 555));
// Invoke a2->B
printf("Result: %d\n", mydelegate.Invoke(a2, 555));
_getch();
delete a1;
delete a2;
return 0;
}