问题
I want to implement the following function:
template<typename Function, typename... Parameters>
inline void foo(
const Function& kernel_function,
bar_t bar
Parameters... parameters)
{
static_assert(/* magic */,
"You can only foo() a function, not values of any other type");
/ * etc. etc. */
}
and I need it to only be called with the identifiers of functions, or with pointers to functions: No lambads or methods or classes with operator()
or std::function
s. What should I replace /* magic */
with? Just using std::is_function
doesn't seem to work.
回答1:
In <type_traits> we have std::is_function which returns true
if you pass it an actual function and false
with lambdas, classes with overloaded operator()
and pointers to functions. We also have std::is_pointer and std::remove_pointer which can be used to check for and remove the pointer type from a function pointer to test the pointer with std::is_function
. Using those your assert would look like
static_assert(std::is_function<Function>::value ||
(std::is_pointer<Function>::value &&
std::is_function<std::remove_pointer<Function>::type>::value),
"You can only foo() a function, not values of any other type");
回答2:
This is based on @DietmarKuhl' answer in the sort-of-duplicate question:
#include <type_traits>
#include <utility>
template<typename Fun>
struct is_function_ptr: std::integral_constant<bool,
std::is_pointer<Fun>::value and
std::is_function<typename std::remove_pointer<Fun>::type>::value> { };
template<typename Function, typename... Parameters>
inline void foo(
const Function& kernel_function,
bar_t bar
Parameters... parameters)
{
static_assert(
std::is_function<Function>::value or is_function_ptr<Function>::value,
"You can only foo() a function, not values of any other type");
/ * etc. etc. */
}
Although, to be honest, I have not tested extensively.
来源:https://stackoverflow.com/questions/43348943/having-trouble-checking-whether-template-parameter-is-something-you-get-when-you