Let's assume, that a class can use the following data-types to pass data to and from it:
std::vector<complex> // where "complex" is a struct
and
std::vector DOUBLE or INT or FLOAT or STRING
If the user passes through a std::vector<double> this implies that a calculation has already been carried out and therefore only a small process has to be completed. If the user, however, passes through std::vector<complex> this means that the calculation has to be carried out.
In a class I can do the following:
class Foo {
template<typename T>
Foo(T begin, T end)
{
this->transform(begin, end);
}
template<typename T>
void transform(T begin, T end)
{
std::cout << "This has been called";
}
};
But this will have to still invoke me having to have a data member of one specific type and always assume they are doing that.
For example, is it possible to override the function transform for 2 different cases, and, have the constructor decide which method to call depending on type of data being passed to the constructor.
It would work something like this:
int main()
{
std::vector<double> vals = {1,1,1,1,1,1,1,1};
Foo(std::begin(vals), std::end(vals)); // this will call the method that handles dbls
std::vector<complex> vals = {};
Foo(std::begin(vals), std::end(vals)); // This will call the method that handles complex numbers
}
I hope this makes sense
This can be solved through template specialization.
Considere the following function:
template<typename T>
void Foo(T arg)
{
std::cout << "General" << std::endl;
}
We can now specialize this function for char types, this means providing another implementation for those types:
template<>
void Foo(char arg)
{
std::cout << arg << std::endl;
}
Notice that the template<> can be omitted in this case.
If we now call our functions like this:
Foo(1);
Foo('a');
The output will be:
General
a
One way would be tag dispatching (I used struct X instead of complex here):
#include <iostream>
#include <vector>
#include <iterator>
struct X {};
struct Foo {
template<typename T>
Foo(T begin, T end)
{
transform(begin, end, typename std::iterator_traits<T>::value_type());
}
template<typename T, typename U>
void transform(T begin, T end, U) // third parameter is unused and serves as a tag
{
std::cout << "floating point\n";
}
template<typename T>
void transform(T begin, T end, X) // same here
{
std::cout << "X\n";
}
};
int main()
{
std::vector<double> v1 = {1,1,1,1,1,1,1,1};
Foo(std::begin(v1), std::end(v1)); // floating point
std::vector<X> v2 = {};
Foo(std::begin(v2), std::end(v2)); // X
}
Related
Let's say I have some arbitrary complicated overloaded function:
template <class T> void foo(T&& );
template <class T> void foo(T* );
void foo(int );
I want to know, for a given expression, which foo() gets called. For example, given some macro WHICH_OVERLOAD:
using T = WHICH_OVERLOAD(foo, 0); // T is void(*)(int);
using U = WHICH_OVERLOAD(foo, "hello"); // U is void(*)(const char*);
// etc.
I don't know where I would use such a thing - I'm just curious if it's possible.
Barry, sorry for the misunderstanding in my first answer. In the beginning I understood your question in a wrong way. 'T.C.' is right, that it is not possible except in some rare cases when your functions have different result types depending on the given arguments. In such cases you can even get the pointers of the functions.
#include <string>
#include <vector>
#include <iostream>
//template <class T> T foo(T ) { std::cout << "template" << std::endl; return {}; };
std::string foo(std::string) { std::cout << "string" << std::endl; return {}; };
std::vector<int> foo(std::vector<int>) { std::cout << "vector<int>" << std::endl; return {}; };
char foo(char) { std::cout << "char" << std::endl; return {}; };
template<typename T>
struct Temp
{
using type = T (*) (T);
};
#define GET_OVERLOAD(func,param) static_cast<Temp<decltype(foo(param))>::type>(func);
int main(void)
{
auto fPtr1 = GET_OVERLOAD(foo, 0);
fPtr1({});
auto fPtr2 = GET_OVERLOAD(foo, std::string{"hello"});
fPtr2({});
auto fPtr3 = GET_OVERLOAD(foo, std::initializer_list<char>{});
fPtr3({});
auto fPtr4 = GET_OVERLOAD(foo, std::vector<int>{});
fPtr4({});
auto fPtr5 = GET_OVERLOAD(foo, std::initializer_list<int>{});
fPtr5({});
return 0;
}
The output is:
char
string
string
vector<int>
vector<int>
I'm probably far from what you have in mind, but I've spent my time on that and it's worth to add an answer (maybe a completely wrong one, indeed):
#include<type_traits>
#include<utility>
template <class T> void foo(T&&);
template <class T> void foo(T*);
void foo(int);
template<int N>
struct choice: choice<N+1> { };
template<>
struct choice<3> { };
struct find {
template<typename A>
static constexpr
auto which(A &&a) {
return which(choice<0>{}, std::forward<A>(a));
}
private:
template<typename A>
static constexpr
auto which(choice<2>, A &&) {
// do whatever you want
// here you know what's the invoked function
// it's template<typename T> void foo(T &&)
// I'm returning its type to static_assert it
return &static_cast<void(&)(A&&)>(foo);
}
template<typename A>
static constexpr
auto which(choice<1>, A *) {
// do whatever you want
// here you know what's the invoked function
// it's template<typename T> void foo(T *)
// I'm returning its type to static_assert it
return &static_cast<void(&)(A*)>(foo);
}
template<typename A>
static constexpr
auto
which(choice<0>, A a)
-> std::enable_if_t<not std::is_same<decltype(&static_cast<void(&)(A)>(foo)), decltype(which(choice<1>{}, std::forward<A>(a)))>::value, decltype(&static_cast<void(&)(A)>(foo))>
{
// do whatever you want
// here you know what's the invoked function
// it's void foo(int)
// I'm returning its type to static_assert it
return &foo;
}
};
int main() {
float f = .42;
static_assert(find::which(0) == &static_cast<void(&)(int)>(foo), "!");
static_assert(find::which("hello") == &static_cast<void(&)(const char *)>(foo), "!");
static_assert(find::which(f) == &static_cast<void(&)(float&)>(foo), "!");
static_assert(find::which(.42) == &static_cast<void(&)(double&&)>(foo), "!");
}
I'll delete this answer after a short period during the which I expect experts to curse me. :-)
I'd like to write a class test that is able to store a function that is able to iterate through a collection of elements identified by the classic [first,last) iterator pair, that is:
template <typename T>
struct sum
{
template <typename I>
T operator()(I first, I last) const
{
T res = 0;
while (first != last)
{
res += *first;
++first;
}
return res;
}
};
//...
int main()
{
test<double> t;
t.set(sum<double>);
double a[] {1.,2.,3.};
std::cout << "Test (array) => " << t.call(a, a+3) << std::endl;
std::vector<double> v {1.,2.,3.};
std::cout << "Test (vector) => " << t.call(v.begin(), v.end()) << std::endl;
std::list<double> l {1.,2.,3.};
std::cout << "Test (list) => " << t.call(l.begin(), l.end()) << std::endl;
}
I thought to use std::function, but I've failed to do this as I wasn't able to declare the templated iterator pair.
A possible workaround is the following, which however only works with plain arrays (e.g., double[] or double*, like the above variable a), but not with other containers (e.g., like the above variables v and l):
template <typename T>
class test
{
public:
template <typename F>
void set(F f)
{
f_ = f;
}
template <typename I>
T call(I first, I last) const
{
return f_(first, last);
}
private:
std::function<T(T*,T*)> f_;
};
Any idea on how can I get the correct behavior?
NOTE: I'm compiling with GCC 4.9.2 --std=c++11
Thank you very much.
What you want is really to be able to construct a:
std::function<T(FwdIter<T>, FwdIter<T>)>
where FwdIter<T> is some type-erased class that satsifes the ForwardIterator concept and is dereferenced to a T. For that, check out the Boost.TypeErasure library, where we can do:
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/operators.hpp>
#include <boost/mpl/vector.hpp>
using namespace boost::type_erasure;
template <typename T>
using FwdIter = any<
boost::mpl::vector<
copy_constructible<>,
incrementable<>,
dereferenceable<T>,
equality_comparable<>
>>;
With that and your definition of sum, I can do:
std::function<int(FwdIter<int>, FwdIter<int>)> f = sum<int>{};
std::vector<int> v = {1, 2, 3, 4, 5};
std::cout << f(v.begin(), v.end()) << std::endl; // prints 15
In your test<T>, you could just have a std::function<T(FwdIter<T>, FwdIter<T>)> member as desired.
I've tried to work on an alternative solution.
Essentially, the user function is wrapped inside a holder holder which fix the function signature to T(const std::vector<T>&). With respect to #Barry's solution (the one I've accepted), this doesn't require external libraries. However it suffers of performance issues due to the construction of the vector object at runtime. Also, and more importantly, as pointed out by #Barry, this solution imposes artificial requirements on T (like T must be copyable).
Here is it:
template <typename T,typename F>
class holder
{
public:
holder(F f) : f_(f) { }
T operator()(const std::vector<T>& v) const
{
return f_(v.begin(), v.end());
}
private:
F f_;
};
template <typename T>
class test_v2
{
public:
template <typename F>
void set(F f)
{
f_ = holder<T,F>(f);
}
template <typename I>
T call(I first, I last) const
{
return f_(std::vector<T>(first, last));
}
private:
std::function<T(const std::vector<T>&)> f_;
};
Why not stoke the functor instead, something like:
template <typename T>
class test
{
public:
template <typename I>
auto call(I first, I last) const
-> decltype(T()(first, last))
{
return T()(first, last);
}
};
And use it:
test<sum<double>> t;
Live example
I have a template class where each template argument stands for one type of value the internal computation can handle. Templates (instead of function overloading) are needed because the values are passed as boost::any and their types are not clear before runtime.
To properly cast to the correct types, I would like to have a member list for each variadic argument type, something like this:
template<typename ...AcceptedTypes> // e.g. MyClass<T1, T2>
class MyClass {
std::vector<T1> m_argumentsOfType1;
std::vector<T2> m_argumentsOfType2; // ...
};
Or alternatively, I'd like to store the template argument types in a list, as to do some RTTI magic with it (?). But how to save them in a std::initializer_list member is also unclear to me.
Thanks for any help!
As you have already been hinted, the best way is to use a tuple:
template<typename ...AcceptedTypes> // e.g. MyClass<T1, T2>
class MyClass {
std::tuple<std::vector<AcceptedTypes>...> vectors;
};
This is the only way to multiply the "fields" because you cannot magically make it spell up the field names. Another important thing may be to get some named access to them. I guess that what you're trying to achieve is to have multiple vectors with unique types, so you can have the following facility to "search" for the correct vector by its value type:
template <class T1, class T2>
struct SameType
{
static const bool value = false;
};
template<class T>
struct SameType<T, T>
{
static const bool value = true;
};
template <typename... Types>
class MyClass
{
public:
typedef std::tuple<vector<Types>...> vtype;
vtype vectors;
template<int N, typename T>
struct VectorOfType: SameType<T,
typename std::tuple_element<N, vtype>::type::value_type>
{ };
template <int N, class T, class Tuple,
bool Match = false> // this =false is only for clarity
struct MatchingField
{
static vector<T>& get(Tuple& tp)
{
// The "non-matching" version
return MatchingField<N+1, T, Tuple,
VectorOfType<N+1, T>::value>::get(tp);
}
};
template <int N, class T, class Tuple>
struct MatchingField<N, T, Tuple, true>
{
static vector<T>& get(Tuple& tp)
{
return std::get<N>(tp);
}
};
template <typename T>
vector<T>& access()
{
return MatchingField<0, T, vtype,
VectorOfType<0, T>::value>::get(vectors);
}
};
Here is the testcase so you can try it out:
int main( int argc, char** argv )
{
int twelf = 12.5;
typedef reference_wrapper<int> rint;
MyClass<float, rint> mc;
vector<rint>& i = mc.access<rint>();
i.push_back(twelf);
mc.access<float>().push_back(10.5);
cout << "Test:\n";
cout << "floats: " << mc.access<float>()[0] << endl;
cout << "ints: " << mc.access<rint>()[0] << endl;
//mc.access<double>();
return 0;
}
If you use any type that is not in the list of types you passed to specialize MyClass (see this commented-out access for double), you'll get a compile error, not too readable, but gcc at least points the correct place that has caused the problem and at least such an error message suggests the correct cause of the problem - here, for example, if you tried to do mc.access<double>():
error: ‘value’ is not a member of ‘MyClass<float, int>::VectorOfType<2, double>’
An alternate solution that doesn't use tuples is to use CRTP to create a class hierarchy where each base class is a specialization for one of the types:
#include <iostream>
#include <string>
template<class L, class... R> class My_class;
template<class L>
class My_class<L>
{
public:
protected:
L get()
{
return val;
}
void set(const L new_val)
{
val = new_val;
}
private:
L val;
};
template<class L, class... R>
class My_class : public My_class<L>, public My_class<R...>
{
public:
template<class T>
T Get()
{
return this->My_class<T>::get();
}
template<class T>
void Set(const T new_val)
{
this->My_class<T>::set(new_val);
}
};
int main(int, char**)
{
My_class<int, double, std::string> c;
c.Set<int>(4);
c.Set<double>(12.5);
c.Set<std::string>("Hello World");
std::cout << "int: " << c.Get<int>() << "\n";
std::cout << "double: " << c.Get<double>() << "\n";
std::cout << "string: " << c.Get<std::string>() << std::endl;
return 0;
}
One way to do such a thing, as mentioned in πάντα-ῥεῖ's comment is to use a tuple. What he didn't explain (probably to save you from yourself) is how that might look.
Here is an example:
using namespace std;
// define the abomination
template<typename...Types>
struct thing
{
thing(std::vector<Types>... args)
: _x { std::move(args)... }
{}
void print()
{
do_print_vectors(std::index_sequence_for<Types...>());
}
private:
template<std::size_t... Is>
void do_print_vectors(std::index_sequence<Is...>)
{
using swallow = int[];
(void)swallow{0, (print_one(std::get<Is>(_x)), 0)...};
}
template<class Vector>
void print_one(const Vector& v)
{
copy(begin(v), end(v), ostream_iterator<typename Vector::value_type>(cout, ","));
cout << endl;
}
private:
tuple<std::vector<Types>...> _x;
};
// test it
BOOST_AUTO_TEST_CASE(play_tuples)
{
thing<int, double, string> t {
{ 1, 2, 3, },
{ 1.1, 2.2, 3.3 },
{ "one"s, "two"s, "three"s }
};
t.print();
}
expected output:
1,2,3,
1.1,2.2,3.3,
one,two,three,
There is a proposal to allow this kind of expansion, with the intuitive syntax: P1858R1 Generalized pack declaration and usage. You can also initialize the members and access them by index. You can even support structured bindings by writing using... tuple_element = /*...*/:
template <typename... Ts>
class MyClass {
std::vector<Ts>... elems;
public:
using... tuple_element = std::vector<Ts>;
MyClass() = default;
explicit MyClass(std::vector<Ts>... args) noexcept
: elems(std::move(args))...
{
}
template <std::size_t I>
requires I < sizeof...(Ts)
auto& get() noexcept
{
return elems...[I];
}
template <std::size_t I>
requires I < sizeof...(Ts)
const auto& get() const
{
return elems...[I];
}
// ...
};
Then the class can be used like this:
using Vecs = MyClass<int, double>;
Vecs vecs{};
vecs.[0].resize(3, 42);
std::array<double, 4> arr{1.0, 2.0, 4.0, 8.0};
vecs.[1] = {arr.[:]};
// print the elements
// note the use of vecs.[:] and Vecs::[:]
(std::copy(vecs.[:].begin(), vecs.[:].end(),
std::ostream_iterator<Vecs::[:]>{std::cout, ' '},
std::cout << '\n'), ...);
Here is a less than perfectly efficient implementation using boost::variant:
template<typename ... Ts>
using variant_vector = boost::variant< std::vector<Ts>... >;
template<typename ...Ts>
struct MyClass {
using var_vec = variant_vector<Ts...>;
std::array<var_vec, sizeof...(Ts)> vecs;
};
we create a variant-vector that can hold one of a list of types in it. You have to use boost::variant to get at the contents (which means knowing the type of the contents, or writing a visitor).
We then store an array of these variant vectors, one per type.
Now, if your class only ever holds one type of data, you can do away with the array, and just have one member of type var_vec.
I cannot see why you'd want one vector of each type. I could see wanting a vector where each element is one of any type. That would be a vector<variant<Ts...>>, as opposed to the above variant<vector<Ts>...>.
variant<Ts...> is the boost union-with-type. any is the boost smart-void*. optional is the boost there-or-not.
template<class...Ts>
boost::optional<boost::variant<Ts...>> to_variant( boost::any );
may be a useful function, that takes an any and tries to convert it to any of the Ts... types in the variant, and returns it if it succeeds (and returns an empty optional if not).
Is there a way in C++ to reflect on the "number of levels of pointer" of a variable, (for example, int* a is 1 level, int** b is 2 levels, and int c is 0 levels)
..Other than using typeid and parsing the string that comes out of that?
The reason I'm asking is I am using pointers to member functions, and I need to know whether to invoke the member function as obj->func() or obj.func(), at compile time really.
If obj is a T**, doing obj.*foo is ill-formed. So you only need to figure out whether it is a pointer or a non-pointer. You can use overloading for this.
template<typename T, typename M> void f(T *obj, M m) { // pointer
(obj->*m)();
}
template<typename T, typename M> void f(T &obj, M m) { // not a pointer
(obj.*m)();
}
This has the drawback that it only works with zero-parameter member function pointers, and it won't return the value (if any) that those functions return. You cannot do the following (which can easily be implemented), because both branches will be type-checked
if(is_pointer(obj)) v = (obj->*m)(arg...); else v = (obj.*m)(args...);
What you can do is to just call a function to dereference your object, if it is a pointer
template<typename T> T &deref(T *t) { return *t; }
template<typename T> T &deref(T &t) { return t; }
Then you can say
v = (deref(obj).*m)(args...);
You could use std::is_pointer from the type_traits header in TR1 (which uses partial specialization to produce an answer), but it might be simpler to just use overload resolution.
Here's an example, assuming void return, no arguments, and no need to handle more than one level of indirection:
template <typename T, typename F>
inline void invoke(T& obj, F func)
{
(obj.*func)();
}
template <typename T, typename F>
inline void invoke(T* obj, F func)
{
(obj->*func)();
}
If you need to handle more than one level of indirection, you can replace the second function with this:
template <typename T, typename F>
inline void invoke(T* obj, F func)
{
invoke(*obj, func);
}
This will recursively strip off levels of indirection until you end up with something that you can invoke your member function on.
Partial template specialization will tell you quite easily:
template<typename T>
struct PtrLevel
{
enum { value = 0 };
};
template<typename TTarget>
struct PtrLevel<TTarget*>
{
enum { value = PtrLevel<TTarget>::value + 1 };
};
Demonstration: http://ideone.com/ZPH8X
In C++0x, you could probably use decltype and SFINAE to handle smart pointers in such a way that they are reported as having a non-zero pointer level.
A bit of template magic to the rescue:
template<typename T>
struct Depth { enum DepthEnum { value = 0 };};
template<typename T>
struct Depth<T*> { enum DepthEnum{ value = Depth<T>::value +1 };};
template<typename T>
size_t getDepth(T const& o)
{
return Depth<T>::value;
}
int main()
{
int a0;
int* a1;
int** a2;
int*** a3;
int**** a4;
int***** a5;
int****** a6;
std::cout << getDepth(a0) << std::endl;
std::cout << getDepth(a1) << std::endl;
std::cout << getDepth(a2) << std::endl;
std::cout << getDepth(a3) << std::endl;
std::cout << getDepth(a4) << std::endl;
std::cout << getDepth(a5) << std::endl;
std::cout << getDepth(a6) << std::endl;
}
Output:
> g++ test.cpp
> ./a.out
0
1
2
3
4
5
6
Going back to the reason you want it. That seems a bit suspect. Your compiler already knows what version to sue at compile time. Remember C++ is very strict on its typing and this information is known at compile time thus if you use the wrong version you will get a compiler error.
I am not aware of any built in way to do this, but you could implement a small template class that simulates a "counting pointer" in the sense that you can easily determine your "pointer depth" like this:
template <typename T> class Ptr {
private:
T* ptr;
int d;
public:
// overload all meaningful operators, like * etc.
// e.g.
T& operator*() {
return *T;
}
int depth() const {
return d;
}
}
as long as your pointer is valid you can use the following code: it'll give you refrence level to the object you pass to it (and just by a little change you can change it to return the object pointers refer to, just use comments instead of acual code and directly use countPartial):
template <class T> int countPartial(T *x,int depth)
//use template <class T> T& countPartial(T *x)
{
return countPartial(*x,depth+1);
//return countPartial(*x);
}
template <class T> int countPartial(T &x,int depth)
//use template <class T> T& countPartial(T &x)
{
return depth;
//return x;
}
template <class T> int count(T x)
{
return countPartial(x,0);
}
probably this shud solve ur trouble
T is template.
funcptr the ptr to function.
int callfunc( T ptr)
{
depth = 0;
if ( typeof(ptr)!= typeof(funcptr))
{
depth++;
depth = depth + callfunc(*ptr);
}
return depth;
}
I do not know if what I am asking is doable, stupid or simple.
I've only recently started dwelling in template functions and classes, and I was wondering if the following scenario is possible:
A class which holds a function pointer to be called. The function pointer cannot be specific, but abstract, so that whenever the class's Constructor is called, it may accept different kinds of function pointers. When the class's execute function is called, it executes the function pointer allocated at construction, with an argument (or arguments).
Basically the abstraction is kept throughout the design, and left over the user on what function pointer and arguments to pass. The following code has not been tested, just to demonstrate what I'm trying to do:
void (*foo)(double);
void (*bar)(double,double);
void (*blah)(float);
class Instruction
{
protected:
double var_a;
double var_b;
void (*ptr2func)(double);
void (*ptr2func)(double,double);
public:
template <typename F> Instruction(F arg1, F arg2, F arg3)
{
Instruction::ptr2func = &arg1;
var_a = arg2;
var_b = arg3;
};
void execute()
{
(*ptr2func)(var_a);
};
};
I do not like the fact I have to keep a list inside the class of possible overloadable function pointers. How could I possibly improve the above to generalize it as much as possible so that it can work with any kind of function pointer thrown at it ?
Bear in mind, I will want to keep a container of those instantiated objects and execute each function pointer in sequence.
Thank you !
Edit: Maybe the class should be a template it'self in order to facilitate use with many different function pointers?
Edit2: I found a way around my problem just for future reference, don't know if it's the right one, but it works:
class Instruction
{
protected:
double arg1,arg2,arg3;
public:
virtual void execute() = 0;
};
template <class F> class MoveArm : public Instruction
{
private:
F (func);
public:
template <typename T>
MoveArm(const T& f,double a, double b)
{
arg1 = a;
arg2 = b;
func = &f;
};
void execute()
{
(func)(arg1,arg2);
};
};
However when importing functions, their function pointers need to be typedef'd:
void doIt(double a, double b)
{
std::cout << "moving arm at: " << a << " " << b << std::endl;
};
typedef void (*ptr2func)(double,double);
int main(int argc, char **argv) {
MoveArm<ptr2func> arm(doIt,0.5,2.3);
arm.execute();
return 0;
}
If you can use C++0x and variadic templates, you can achieve this by using combination of std::function, std::bind and perfect forwarding:
#include <iostream>
#include <functional>
template <typename Result = void>
class instruction
{
public:
template <typename Func, typename... Args>
instruction(Func func, Args&&... args)
{
m_func = std::bind(func, std::forward<Args>(args)...);
}
Result execute()
{
return m_func();
}
private:
std::function<Result ()> m_func;
};
double add(double a, double b)
{
return (a + b);
}
int main()
{
instruction<double> test(&add, 1.5, 2.0);
std::cout << "result: " << test.execute() << std::endl;
}
Example with output: http://ideone.com/9HYWo
In C++ 98/03, you'd unfortunately need to overload the constructor for up-to N-paramters yourself if you need to support variable-number of arguments. You'd also use boost::function and boost::bind instead of the std:: equivalents. And then there's also the issue of forwarding problem, so to do perfect forwarding you'd need to do an exponential amount of overloads depending on the amount of arguments you need to support. Boost has a preprocessor library that you can use to generate the required overloads without having to write all the overloads manually; but that is quite complex.
Here's an example of how to do it with C++98/03, assuming the functions you pass to the instruction won't need to take the arguments by modifiable reference, to do that, you also need to have overloads for P1& p1 instead of just const P1& p1.
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
template <typename Result = void>
class instruction
{
public:
template <typename Func>
instruction(Func func)
{
m_func = func;
}
template <typename Func, typename P1>
instruction(Func func, const P1& p1)
{
m_func = boost::bind(func, p1);
}
template <typename Func, typename P1, typename P2>
instruction(Func func, const P1& p1, const P2& p2)
{
m_func = boost::bind(func, p1, p2);
}
template <typename Func, typename P1, typename P2, typename P3>
instruction(Func func, const P1& p1, const P2& p2, const P3& p3)
{
m_func = boost::bind(func, p1, p2, p3);
}
Result execute()
{
return m_func();
}
private:
boost::function<Result ()> m_func;
};
double add(double a, double b)
{
return (a + b);
}
int main()
{
instruction<double> test(&add, 1.5, 2.0);
std::cout << "result: " << test.execute() << std::endl;
}
Example: http://ideone.com/iyXp1
I also created a C++0x version with some example usage. You can probably better use the one given by reko_t but I nevertheless post this one. This one uses recursion to unpack a tuple with values, and thus a tuple to store the arguments to pass to the function. Note that this one does not use perfect forwarding. If you use this, you probably want to add this.
#include <iostream>
#include <string>
#include <tuple>
using namespace std;
template<unsigned N>
struct FunctionCaller
{
template<typename ... Typenames, typename ... Args>
static void call(void (*func)(Typenames ...), tuple<Typenames ...> tuple, Args ... args)
{
FunctionCaller<N-1>::call(func, tuple, get<N-1>(tuple), args ...);
}
};
template<>
struct FunctionCaller<0u>
{
template<typename ... Typenames, typename ... Args>
static void call(void (*func)(Typenames ...), tuple<Typenames ...> tuple, Args ... args)
{
func(args ...);
}
};
template<typename ... Typenames>
class Instruction
{
public:
typedef void (*FuncType)(Typenames ...);
protected:
std::tuple<Typenames ...> d_args;
FuncType d_function;
public:
Instruction(FuncType function, Typenames ... args):
d_args(args ...),
d_function(function)
{
}
void execute()
{
FunctionCaller<sizeof...(Typenames)>::call(d_function, d_args);
}
};
void test1()
{
cout << "Hello World" << endl;
}
void test2(int a, string b, double c)
{
cout << a << b << c << endl;
}
int main(int argc, char** argv)
{
Instruction<> i1(test1);
Instruction<int, string, double> i2(test2, 5, "/2 = ", 2.5);
i1.execute();
i2.execute();
return 0;
}
Well, what you are doing is correct. But since all pointers have the same size in C++ you can store one pointer (of void type):
void *funcptr;
and cast it to the necessary type when needed:
static_cast<(*void)(double,double)>(funcptr)(var_a, var_b);
But please, only use this when better techniques can not be used, but I can not tell if you don't tell us the bigger picture.
You might want to look at boost::function.