C++, pass a function of n arguments as an argument - c++

Let us suppose that we have a function of n variables
y = f (x1, ..., xn)
Such a function I would like to pass as an argument.
In Matlab the following construction using a handle is available:
function y=func(x)
y = sin(x(0)) * cos(x(1)) //Any definition, not important
p_func=#func; //Define handle
It is possible to use the handle as a parameter of another function:
y = function2(p_func, n);
where n represents a dimension...
How to rewrite this code using C++? We use a simple model with the function template
temmplate <typename T>
T func( const T *arg, const short n) {return sin(arg[0]) * cos(arg[1])};
where xi arguments are represented by the 1-dimensional array of n elements. The problem is that in this case it is not possible to use a pointer to the function template
template <class T>
static T ( *pfunc ) ( const T *arg, const short n )
only a specialization... Perhaps another model could be more appropriate...Thanks for your help...
Remark:
I know that a class template is useful
template <typename T>
class Foo
{
T func( const T *args, const short n);
};
and this construction works:
template <class T>
static T ( *pfunc ) ( const T *arg, const short n )
But it may not be used in the current model of the library (I can not affect this).

C++ is a statically typed language. Every object in C++, whether a function pointer, or whatever, must have a specific type. And the type of a function pointer is based on the types of arguments that the function to be pointed to is given.
A template is not an object, so you can't get a pointer to one. You can get a pointer to an instantiation of a template. Using your func definition, func<int> is a function that takes a const int* and a short. You can get a pointer to func<int>. But func is a template; you can't get a pointer to a template.
That's why C++ programs often throw functors around instead of function pointers. Functors can have a template operator() method, so you can call them as though you were passing around template functions. But since you say that you have to use a function pointer, there's not much that can be done.

The problem is not the "n". The problem is the templated type T.
Are you trying to declare a variable (of type pointer to function), here?
template <class T>
static T ( *pfunc ) ( const T *arg, const short n )
This will not work without instantiating the template.
This is because of otherwise, type checking would be impossible. The type checker could not check if, when you initialized the pointer, T was the same as when you dereference it.
You will probably need to look at a bigger context. Where do you want to USE that declaration? Move the template parameter to that context.
For example, you could have a function, or class with template parameter T.
There, you could declare, initialize and dereference any function pointer which has T somewhere in it's type.
Maybe you can "bind" the parameters at the place where you assign the function pointer. So the resulting function will be a nullary function, which you can use without knowing the parameter types.

You cannot obtain pointer to template function, because template is not an object, it's just compile-time syntax construction producing multiple specific functions - template instantiations. Template instantiations, e.g. f<int>(const int*, short) are objects and can be pointed.
If you just want some simple and unified way to obtain function pointer from template instantiation, use declspec() (I'm supposing you are using modern C++11 compatible compiler):
template <class T> static T f(const T *, const short )
{
// Implementation
...
}
// Declaring function pointers for int & double
typedef decltype(&f<int>) IntFuncPtr;
typedef decltype(&f<double>) DoubleFuncPtr;
// Sample usage
IntFuncPtr intFunc = &f<int>;
intFunc(NULL, 0);
DoubleFuncPtr doubleFunc = &f<double>;
doubleFunc(NULL, 0);

I don't think this is easily solved in C++, but there are approaches for similar cases. You should take a look at the boost::bind and boost::function library. It was made for getting around the nasty details of passing function pointers around in C++ (and they allow to pass for class methods as well). As far as i recall they don't really use a generic N but instantiate templates for arbitrary N parameters. It's definitely worth a look if you want to get to something similar.

Related

C++ - Declare pointer to function returning any type and getting any number of parameters

I was wondering if writing anything resembling this declaration (making use of the parameter pack) is possible.
decltype(auto) (*funcPtr)(...);
If possible, I would also like to know about alternative ways to declare such a pointer.
C++ is a statically typed language. All function argument types and return types must be known at compile time. You cannot declare a function that returns arbitrary types (well, I guess you could return std::any, but I can't think of a case where you'd want to).
You can use templates, however, to create function templates where the compiler will stamp out multiple versions of a function for you, so you don't have to write them all yourself.
Remember that auto and decltype(auto) is not magic. They are just syntactic sugar for what you'd otherwise write yourself if they didn't exist. They do not enable any new features that weren't already in the language. They just make such features easier to use.
No, there is no type such as pointer to function "that returns anything". There are only pointers to a function that returns some type or void. auto merely deduces the type from an initialiser, and there is nothing to deduce the type from in your example.
You can however have a function template where the instance of the template is a function that returns a type specified by a template argument:
// function template
template<class T>
T foo() {
return {};
}
Likewise, you can have a variable template that is a pointer to function whose return type is specified by a template variable:
// variable template
template<class T>
T (*funcPtr)() = foo;
// example usage
int main() {
return funcPtr<int>();
}

How to create a get() member function for a std::tuple

My problem is std::tuple has no member function like
auto t = std::make_tuple(1,2,"foo");
t.get(1);
how can I implement such a function when I create a wrapper class arround std::tuple
Such a function cannot exist (in current C++ standards) because function arguments are a run-time mechanism, but return types need to be known at compile time. So the latter cannot depend on the former.
Use std::get instead:
auto v = std::get<1>(someTuple);
To get a value from a tuple you should use std::get<0>(tuple)
You can't have a get function like you want, because tuple elements are not necessarily of the same type (in your example you have ints and a string). What would the return type of this get function be?
You can add a template get function, so that derived_tuple.get<0>() will return the first element.
There are actually two questions here. The first is
why get has a template integral argument rather than a accepting this
value as a function argument.
This has been answered.
The other question is
why get is a free function rather than a member function
To this the answer seem to be - so that called on templated types, it would not require usage of keyword typename. Example. Suppose, tuple would have a get as a member, it would have to be called like that in below code:
template <class T> void foo(T tuple) {
tuple.template get<1>() = 42;
}
This template is certainly a nuisance.

std::function type and template instantiation

I'm new to C++ and I'm learning about lambdas,functors and callables, and I know that there's a wrapper class, namely std::function that allows callables of different types to be stored and called (as long as the have the same call signature,or function type).
Now, I understand that you can have function with function type parameters that are really just function pointer parameters as in :
void fun(int,int*(int,int&));
which is nothing more than a function that takes an int and a function pointer to a function like int *f(int,int&),even if the language allows me to pass a function as an argument (with or without the ampersand).Infact, the function parameter list might as well be written as:
void fun(int,int*(*)(int,int&));
Now,back to the std::function type
I know that I can instantiate std::function with a function type and that allows any kind of callable to be passed to the wrapper. But, a function type is not a type I can use as a template type argument in any instantiation such as:
std::vector<int(int)> f_vec;
instead, I should make a vector of function pointers
std::vector<int(*)(int)> f_vec;
and that would allow me to insert pointers to function,but not functors or lambdas.
So, my question is, how can I instantiate a template with a type argument like a function type?? what's happening under the hood in the library std::function type.I mean a function type seems to me a type I cannot use in templates?? pleas can you make things a little clearer,as I'm just beginning to learn these topics. Thanks
The reason why you cannot write std::vector<int(int)> is not something fundamental about using function types as template parameters. That's perfectly valid. It's just what std::vector<T> does with the T (like operate on it by value) which makes std::vector<int(int)> illegal.
This can be shown by using std::vector<int(int)> in a context where nothing bad happens, such as this:
typedef std::vector<int(int)> StillOk;
StillOk *p = nullptr;
As long as the template doesn't actually try to do anything illegal with int(int), it's fine.
So, as long as your template deals with its template parameter in a way which is legal for function types, you can use it with function types. Here's a hypothetical example:
template <class T>
struct MyPointer
{
T *p;
T& operator* () const { return *p; }
};
It's now perfectly legal to instantiate MyPointer<int(int)> and use its operator *, because it will only ever involve expressions of type int (*)(int) and int (&)(int). [Live example]
And that's pretty much also what std::function<T> does with its T—only things which are legal with a function type.

Reason for using non-type template parameter instead of regular parameter?

In C++ you can create templates using a non-type template parameter like this:
template< int I >
void add( int& value )
{
value += I;
}
int main( int argc, char** argv )
{
int i = 10;
add< 5 >( i );
std::cout << i << std::endl;
}
Which prints "15" to cout. What is the use for this? Is there any reason for using a non-type template parameter instead of something more conventional like:
void add( int& value, int amount )
{
value += amount;
}
Sorry if this has already been asked (I looked but couldn't find anything).
There are many applications for non-type template arguments; here are a few:
You can use non-type arguments to implement generic types representing fixed-sized arrays or matrices. For example, you might parameterize a Matrix type over its dimensions, so you could make a Matrix<4, 3> or a Matrix<2, 2>. If you then define overloaded operators for these types correctly, you can prevent accidental errors from adding or multiplying matrices of incorrect dimensions, and can make functions that explicitly communicate the expected dimensions of the matrices they accept. This prevents a huge class of runtime errors from occur by detecting the violations at compile-time.
You can use non-type arguments to implement compile-time function evaluation through template metaprogramming. For example, here's a simple template that computes factorial at compile-time:
template <unsigned n> struct Factorial {
enum {
result = n * Factorial<n - 1>::result
};
};
template <> struct Factorial<0> {
enum {
result = 1
};
};
This allows you to write code like Factorial<10>::result to obtain, at compile-time, the value of 10!. This can prevent extra code execution at runtime.
Additionally, you can use non-type arguments to implement compile-time dimensional analysis, which allows you to define types for kilograms, meters, seconds, etc. such that the compiler can ensure that you don't accidentally use kilograms where you meant meters, etc.
Hope this helps!
You're probably right in this case, but there are cases where you need to know this information at compile time:
But how about this?
template <std::size_t N>
std::array<int, N> get_array() { ... }
std::array needs to know its size at compile time (as it is allocated on the stack).
You can't do something like this:
std::array<int>(5);
Well, this the typical choice between compile-time polymorphism and run-time polymorphism.
From the wording of your question in appears that you see nothing unusual in "ordinary" template parameters, while perceiving non-type parameters as something strange and/or redundant. In reality the same issue can be applied to template type parameters (what you called "ordinary" parameters) as well. Identical functionality can often be implemented either through polymorphic classes with virtual functions (run-time polymorphism) or through template type parameters (compile-time polymorphism). One can also ask why we need template type parameters, since virtually everything can be implemented using polymorphic classes.
In case of non-type parameters, you might want to have something like this one day
template <int N> void foo(char (&array)[N]) {
...
}
which cannot be implemented with a run-time value.
In that particular instance, there's not really any advantage. But using template parameters like that, you can do a lot of things you couldn't do otherwise, like effectively bind variables to functions (like boost::bind), specify the size of a compile-time array in a function or class (std::array being a ready example of that), etc.
For instance, with that function, you write a function like
template<typename T>
void apply(T f) {
f(somenum);
}
Then you can pass apply a function:
apply(&add<23>);
That's an extremely simple example, but it demonstrates the principle. More advanced applications include applying functions to every value in a collection, calculating things like the factorial of a function at compile time, and more.
You couldn't do any of that any other way.
There are lots of reasons, like doing template metaprogramming (check Boost.MPL). But there is no need to go that far, C++11's std::tuple has an accessor std::get<i> that needs to be indexed at compile time, since the result is dependent on the index.
The most frequent use for a value parameter that I can think of is std::get<N>, which retrieves the Nth element of a std::tuple<Args...>. The second-most frequent use would be std::integral_constant and its main derivatives std::true_type and std::false_type, which are ubiquitous in any sort of trait classes. In fact, type traits are absolutely replete with value template parameters. In particular, there are SFINAE techniques which leverage a template of signature <typename T, T> to check for the existence of a class member.

Passing function as class template argument

Without knowing a function's type, I am declaring its pointer with below technique and initializing a function pointer.
template<typename T>
struct Declare { typedef T Type; }; // for declaring any func ptr
void fun () {}
int main ()
{
Declare<fun>::Type pf = &fun; // can't use C++0x 'auto'
}
However, it gives compile error as, error: expected a type, got ‘fun’. Though the type of any method is known at compile time. Is it invalid to pass a function into a class template as above ?
[Note: replacing fun with void (*)() works fine. But that's not what want.]
Is it invalid to pass a function into a class template as above ?
Totally yes, you're mixing up type and non-type parameters.
fun is a non-type argument, it's an address of a function, like an arbitary number 0x12345678.
typename T is a type parameter. You can only pass it types, like int,MyClass, double (*)(std::string), void (MyClass::*)().
You'll just have to life with the fact, that you need compiler support for that stuff or some really ugly trickery to deduce the type.
If you're in for the trickery, there's Boost.Typeof for non-C++0x coder like you. It also provides a stand-in for auto with BOOST_AUTO, but that is only a short way for writing BOOST_TYPEOF:
int hello(){ return 42; }
BOOST_AUTO(var1,hello()); // type of var1 == int
BOOST_TYPEOF(hello()) var2 = hello(); // same
The problem? You need to help it for every user-defined type you have. See this Ideone example.
Now, most of the time I don't think you need Boost.Typeof. Why? Because if you use a function, you of course need to know the signature, how would you pass the correct arguments otherwise? Or use the return type in a correct way?
The other times are the usage in templates anyways. If you declare a function pointer like auto fptr = &func, then you have the knowledge, that func exists, aka you know its signature and type. For when you don't know that func exists, you need it passed to you anyways, preferably in a template:
template<class FPtr>
void myfunc(FPtr otherfunc){
// use otherfunc
}
And with a template you have the knowledge of that functions type again.
Is it invalid to pass a function into a class template as above?
Yes. Because what you, in other words, want the compiler to deduce the type parameter for the class template, which simply not possible in C++. Recall that fun itself isn't a type, its a value of type void (*)(). But your class template expects type, not value. That's why it wouldn't work.
Type deduction is possible with functions only, that means even with the constructor of class. So if you write a templated constructor, and then you can write this:
Declare obj(&fun);
Here the type of the function is known as long as you're in constructor, once you exist from it, you lost the information. So what you probably need is : define a class, say, AbstractFunctor (possibly class template) and derived from it defining an another class say template<Fun fun> struct Functor. Then you can create an instance of Functor which can remember the function type forever, and store the instance in AbstractFunctor* as a member data of Declare.
But I think, even in this way, the type cannot be used as Declare::Type or Declare::AbstractFunctor::Type, simply because the type is stored in an instance of the class; only the instance knows the type. So the getting type using syntax like A::Type is out of the question. And you cannot get type using syntax instance.Type either. All you can do is : call the function, using the instance, like a functor.
EDIT:
If you're allowed to use C++0x's other features (excluding auto), then the problem has a trivial solution:
Declare<decltype(&fun)>::Type pf = &fun;
pf(); //call the function
Demo : http://ideone.com/
But then, you don't need even Declare, as you can do this instead:
decltype(&fun) pf = &fun;
pf(); //call the function