一 可构造性判断std::is_invocable
template <class T, class... Args> struct is_constructible;
T是待检查的类型,Args为可变参数
例如:
struct A {
A (int,int) {
};
};
std::cout << "A(int): " << std::is_constructible<A ,int>::value << std::endl; // false
std::cout << "A(int,int): " << std::is_constructible<A, int, int>::value << std::endl; // true A的构造函数是A(int, int)
二 引用包裹器std::reference_wrapper
template< class T >
class reference_wrapper;
引用包裹器:可以包裹一个指向对象或者指向函数指针的引用,既可以通过拷贝构造,也可以通过赋值构造。
int func(int a, int b) {
return a + b;
}
std::reference_wrapper<int(int,int)> ref_func = func;
auto sum = ref_func(5,7);
三 对std::is_invocable的封装struct is_invocable
#include <functional>
#include <cassert>
template <typename F, typename... Args> // 函数类型 + 可变参数
struct is_invocable : std::is_constructible<std::function<void(Args ...)>, std::reference_wrapper<typename std::remove_reference<F>::type>> {
};
std::string fun(std::string &a, std::string &b) {
return a + b;
}
struct person {
std::string fun(std::string a, std::string b) {
return a + b;
}
};
int main() {
static_assert(is_invocable<decltype(fun), std::string &, std::string &>::value, "not match"); // 编译成功
static_assert(is_invocable<decltype(fun), std::string &, std::string >::value, "not match"); // 编译失败 输出not match
static_assert(is_invocable<decltype(&person::fun), person &, std::string, std::string>::value, "not match");// 编译成功
return 0;
}
编译:g++ -std=c++11 -g -o Test test.cpp