std::is_function does not recognize template argument as function
Asked Answered
E

1

12

I am passing a pointer to function into a function template:

int f(int a) { return a+1; }

template<typename F>
void use(F f) {
    static_assert(std::is_function<F>::value, "Function required"); 
}

int main() {
    use(&f); // Plain f does not work either.
}

But the template argument F is not recognized by is_function to be a function and the static assertion fails. Compiler error message says that F is int(*)(int) which is a pointer to function. Why does it behave like that? How can I recognize the function or pointer to function in this case?

Eileneeilis answered 6/5, 2013 at 8:52 Comment(0)
C
15

F is a pointer to function (regardless of whether you pass f or &f). So remove the pointer:

std::is_function<typename std::remove_pointer<F>::type>::value

(Ironically, std::is_function<std::function<FT>> == false ;-))

Casebook answered 6/5, 2013 at 9:1 Comment(4)
I loathe implicit conversions :(Photosensitive
"(Ironically, std::is_function<std::function<FT>> == false ;-))" - Maybe for future standards a std::is_callable might be a good idea, since std::is_function doesn't even work for lambdas, just simple functions (and the times each callable was a function are way over in modern C++).Proconsul
@ChristianRau std::is_function is one of the primary classification traits. is_callable or anything like that would serve a completely different purpose altogether.Kentigera
@LucDanton Yes, of course. Nobody argues that std::is_function has its value and fits perfectly to things like std::is_array (which should not return true for std::array either) or std::is_class. But nevertheless an additional std::is_callable would be a nice idea and would be in line with other rather high-level traits, like (the AFAIK already proposed) std::is_swappable and the desperately needed (though AFAIK not proposed) std::is_hashable.Proconsul

© 2022 - 2024 — McMap. All rights reserved.