Gonen I
Gonen I

Reputation: 6107

stl function and function type vs function pointer type

I am trying to understand the difference between function types <void()> and function pointer types <void (*)()>

stl::function can point to functions through <void()>, but I seem to need to use <void (*)()> in my own template classes:

void f1() {
    std::cout << "hi!\n";
}
template<class T> struct X
{
    T t;
};
int main()
{
    std::function<void()> f = f1;  // stl handles this, and f is callable
    f(); // OK

    // X<void()> x; // compilation error - a member of a class template cannot aquire a function type

    X<void (*)()> x2;  // OK
    x2.t = f1;  // OK
    x2.t();  // OK

    return 0;
}

Are function types such as <void()> new to C++ 11, and introduced along with std::function?

I have seen some other questions regarding this, but have not found an explanation which is clear to me, and searching the web for C++ function type does not yield satisfactory results.

I would greatly appreciate any clear explanation or references to one.

Upvotes: 3

Views: 212

Answers (2)

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153830

Function types aren’t new to C++11 at all: the existed even in C. However, you cannot have objects of function types, i.e.,

template <typename T>
struct X {
    T t;
};

X<void()>    does_not_work;
X<void(*)()> works;

However, you can turn a function type into a pointer type:

template <typename T>
struct X {
    T* t;
};

Upon using a function differently than calling it the function decays into a function pointer. Decaying a function into a pointer is equivalent to taking the function’s address.

Of course, what std::function<...> does is quite different anyway: it actually defines a function call operator. To do so it deckares a general template and specializes it for function types:

template <typename> class function;
template <typename R, typename... A>
class function<R(A...)> {
public:
    R operator()(A...);
    // ...
};

Upvotes: 6

Alan Birtles
Alan Birtles

Reputation: 36389

You can't store a function in a variable, you can only store a function pointer. What is slightly confusing is that the language automatically converts a function into a function pointer when you try to assign the function name to a variable.

Your class would have to be:

template<class T> struct X
{
    T* t;
};

To make X<void()> x work. This would of course stop X<void (*)()> x2 from working, you'd have to specialise the template for different types.

Upvotes: 3

Related Questions