3

With reference to the following code

#include <iostream>
using std::cout;
using std::endl;
#include <vector>
using std::vector;

void function() {
    cout << "Hello World" << endl;
}

int main() {
    vector<void (*) ()> functions;
    functions.push_back(function);         // (1) no error
    functions.push_back(&function);        // (2) no error
    for (const auto& func : functions) {
        func();
    }

    // vector<decltype(function)> vec;     // (3) error
    return 0;
}

There seems to be an error when I uncomment (3), I am just trying to understand the reasoning behind this. When I pass in a function as the argument to a templated function does it resolve the type to a function pointer? It would make sense for the compiler to deduce all function types as such to a function pointer but why then does the decltype() not resolve to a function pointer?

2
  • 1
    I don't have an answer, but I recommend the use of std::function instead of function pointers. It's more readable, and you don't deal with whether it is a pointer or not. Commented Feb 3, 2016 at 17:29
  • @AdiLevin std::function should only be used when necessary, that is when one really wants to store (!) callables that have nothing in common but being callable (with the respective arguments, returning the respective type). It adds a lot of overhead. Commented Feb 3, 2016 at 17:32

1 Answer 1

7

decltype(function) is void() - a function.
what you need is the decayed version of a function - void(*)():

std::decay<decltype(function)>::type

std::vector < std::decay<decltype(function)>::type > myPtrFunctionVec;

PS.
if you're working with VC++ (visual stdio) you can easily see the type deduced from decltype by printing typeid(decltype(XXX)).name(). VC++, unlike other compilers, gives the undecorated name of a type. very handy for metaprogramming debugging.

EDIT:
as @Daniel Jour has commented, the solution decltype(&function) workd as well, because the construct &f gives the pointer to f, which is what you need

Sign up to request clarification or add additional context in comments.

8 Comments

std::decay is a good idea, wasn't thinking of it. You could also just decltype(&function): ideone.com/Af98uJ
@DanielJour cool! I wasn't aware that that expression will yield a pointer to function!
@DavidHaim Nor was I. It's one of those things that you wouldn't think would work, until you look at it again and realise it makes perfect sense. &function is a function pointer, so logically passing it to decltype would evaluate to the function pointer's type. It's just too simple to be obvious, though.
the functions sit somwhere else in the memory as assembly instructions, you can't store that in a vector. what you can store is a pointer to something that will initialize a call to the assembly instructions. you can't store functions, only pointer to functions
well, technically, if you write a JIT compiler, you can, but that is completly different talk
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.