3

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

Luca
  • 1,658
  • 4
  • 20
  • 41

1 Answers1

8

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.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • ok, so I understand that the topic is indeed deeper and that I need to delve into it a "little" more... but now you got me confused, I know about function pointers, but function references?? – Luca Aug 31 '15 at 07:52
  • @Luca Yes, function references exist as well. `void (&alias)() = foo;` is perfectly valid. – Angew is no longer proud of SO Aug 31 '15 at 07:53
  • and what's their use? I mean, if I define a function parameter of function type, that is treated automatically as a function pointer, so how do function references fit into the picture? – Luca Aug 31 '15 at 07:54
  • @Luca The question goes the other way round - what would anyone get from forbidding them (apart from complicating compilers)? – Angew is no longer proud of SO Aug 31 '15 at 07:55
  • yes, but it just seems to me that the usage for the two types kind of overlaps? – Luca Aug 31 '15 at 07:56
  • @Luca So does usage of `int` and `long`, to a large degree ;-) Or of pointers and references in general. Still, even my trivial "pointer class" example shows that it's good for generic code that stuff is not prohibited arbitrarily. – Angew is no longer proud of SO Aug 31 '15 at 08:00
  • yes, I'm digressing here :) I got your point anyway, and I think that I need to study templates more in order to get the answer right, thanks – Luca Aug 31 '15 at 08:02
  • @Luca In case it comes in handy, we keep a [list of good C++ books](http://stackoverflow.com/q/388242/1782465) here on SO. – Angew is no longer proud of SO Aug 31 '15 at 08:04
  • thanks, I'm actually more than half-way through Lippmann's C++11 primer and I find it a very valid book. I think my next move will be tackling Stroustroup's bible, C++ programming language. I know Java and I'm keeping studying it as well, so it's quite challenging but I like it! ;) – Luca Aug 31 '15 at 08:06