Understanding the template argument to std::function in C++11?

460 views Asked by At

I am brushing up on some C++11 and am having a bit of a hard time understanding something.

std::function lets me pass any Callable type as a function object. I know what it does and how to use it.

void foo(int a, int b) {} 
std::function<void (int, int)> bar = foo;
...

bar is a callable object who'se target is foo, a function that takes two ints as parameters.

What I don't understand is exactly what void (int, int) means...

  • I know it is the template parameter I am giving the compiler.
  • I know that from it the compiler interprets that the callable type must take two ints and return void.

But, void (int, int) doesn't appear to "name a type".

  • void (*)(int, int) is a pointer to a void returning function that takes two ints
  • void (Foo*::)(int, int) is a pointer to Foo's void returning function that takes two ints

In fact the following toy snippet compiles fine.

class Foo {};
int main(int, char**)
{
    void (*)(int, int);
    void (Foo*::)(int, int);
}

But adding the expression void (int, int) causes a compile time error.

I did a little bit more digging around before posting my question. The following code snippet compiles:

class Foo {};

template <typename T>
struct Bar
{
    typedef T type;
};

void a(int b, int c) {}

int main(int, char**)
{
    void (*)(int, int);
    void (Foo::*)(int, int);

    Bar<int (int, int)> bar;
}

But attempting to use Bar::type in any way produces another error: "invalidly declared function type".


TLDR: What exactly does the expression void (int, int) mean and why is it a valid template parameter?

Thanks for any help you can send my way.

2

There are 2 answers

2
JDR On

dyp pointed me to the correct answer. This was a duplicate question.

void (int, int) represents a "function signature" and function signatures can be passed as template parameters.

0
Yakk - Adam Nevraumont On

Not all types have values. void is the most well know example.

void(int,int) is just a type that is the type of no values. And it is useful, so it is used.

The type can be used outside of template arguments in a few spots. For example, it can be used to declare a method or a function, or a pointer to the type can be used as a function pointer, or a reference as a function reference.