is_function functors/function-objects 的类型特征
is_function type trait for functors/function-objects
考虑以下代码:
struct Bar {
void operator()() {}
};
int main() {
std::cout << std::boolalpha << std::is_function<Bar>::value <<
}
输出为false
。
这里并不奇怪,因为函子 Bar
不符合函数类型 §8.3.5 函数 [dcl.fct].
现在考虑以下代码:
struct Bar {
void operator()() {}
};
int main() {
std::cout << std::boolalpha << std::is_function<Bar()>::value << std::endl;
^^
}
注意 Bar
后的括号。输出为 true
.
Bar()
如何限定为函数类型?
我的猜测是这是一个最令人烦恼的解析案例,但它在模板参数列表中怎么可能呢?
好吧,我不认为它是 MVP,它只是 returns Bar
并且不带任何参数的函数类型。
就是这个功能
Bar foo();
类型为 Bar()
.
自然而然,std::is_function<Bar()>::value
就是true
。
这将是相同的:
typedef Bar F();
std::cout << std::is_function<F>::value << std::endl;
验证 Bar
是否可调用 std::is_function
没有帮助。为此,您需要做其他事情。基于通用代码(取自):
template<class F, class... T, typename = decltype(std::declval<F>()(std::declval<T>()...))>
std::true_type supports_test(const F&, const T&...);
std::false_type supports_test(...);
template<class> struct supports;
template<class F, class... T> struct supports<F(T...)>
: decltype(supports_test(std::declval<F>(), std::declval<T>()...)){};
你可以做到
struct Bar {
void operator()() {}
void operator()(double) {}
};
int main(){
static_assert( supports<Bar()>::value == true , "");
static_assert( supports<Bar(double)>::value == true , ""); // because of overload
static_assert( supports<Bar(int)>::value == true , ""); // because of conversion
static_assert( supports<Bar(std::string)>::value == false , "");
}
考虑以下代码:
struct Bar {
void operator()() {}
};
int main() {
std::cout << std::boolalpha << std::is_function<Bar>::value <<
}
输出为false
。
这里并不奇怪,因为函子 Bar
不符合函数类型 §8.3.5 函数 [dcl.fct].
现在考虑以下代码:
struct Bar {
void operator()() {}
};
int main() {
std::cout << std::boolalpha << std::is_function<Bar()>::value << std::endl;
^^
}
注意 Bar
后的括号。输出为 true
.
Bar()
如何限定为函数类型?
我的猜测是这是一个最令人烦恼的解析案例,但它在模板参数列表中怎么可能呢?
好吧,我不认为它是 MVP,它只是 returns Bar
并且不带任何参数的函数类型。
就是这个功能
Bar foo();
类型为 Bar()
.
自然而然,std::is_function<Bar()>::value
就是true
。
这将是相同的:
typedef Bar F();
std::cout << std::is_function<F>::value << std::endl;
验证 Bar
是否可调用 std::is_function
没有帮助。为此,您需要做其他事情。基于通用代码(取自):
template<class F, class... T, typename = decltype(std::declval<F>()(std::declval<T>()...))>
std::true_type supports_test(const F&, const T&...);
std::false_type supports_test(...);
template<class> struct supports;
template<class F, class... T> struct supports<F(T...)>
: decltype(supports_test(std::declval<F>(), std::declval<T>()...)){};
你可以做到
struct Bar {
void operator()() {}
void operator()(double) {}
};
int main(){
static_assert( supports<Bar()>::value == true , "");
static_assert( supports<Bar(double)>::value == true , ""); // because of overload
static_assert( supports<Bar(int)>::value == true , ""); // because of conversion
static_assert( supports<Bar(std::string)>::value == false , "");
}