Mat*_*ano 5 c++ templates sfinae c++11
我写了一个快速的东西,它确定给定的类型(和参数)是否可以转换为普通的函数指针.它的工作原理如下:
template <typename F, typename...Args>
struct is_stateless : std::is_convertible<F, typename std::result_of<F(Args...)>::type (*) (Args...)>::type
{};
Run Code Online (Sandbox Code Playgroud)
这在大多数情况下运作良好,但它有一个严重的缺点:使用std::result_of<F(Args...)>::type.如果你不小心为你的函数提供了错误的参数(假设你没有离开&),你会因为result_of没有type字段而得到模板错误.我更喜欢我的is_stateless结构,只是在这种情况下,"假"(因为如果你提供的"正确"的函子,并且没有发生可以转换成一个函数指针参数这将是).
我愿意使用GCC4.8.*及更低版本中的C++ 11和c ++ 1y功能.有关如何做到这一点的任何想法?
小智 1
不允许实例化不正确的result_of<F(Args...)>地方。如果您无论如何都这样做,则无法从错误中恢复。ArgsF
您可以做的是避免使用result_of:您可以使用 达到相同的结果decltype(declval<F>()(declval<Args>()...))。这也应该适用于 SFINAE 上下文:
#include <utility>
#include <vector>
template <typename F, typename...Args>
void funcptr_helper(...);
template <typename F, typename...Args>
auto funcptr_helper(F, Args...) -> decltype(std::declval<F>()(std::declval<Args>()...));
template <typename F, typename...Args>
struct funcptr {
typedef decltype(funcptr_helper<F, Args...>(std::declval<F>(), std::declval<Args>()...)) (*type)(Args...);
};
template <typename F, typename...Args>
struct is_stateless : std::is_convertible<F, typename funcptr<F, Args...>::type>::type {};
int main() {
auto f1 = [](int i){ return i; };
static_assert(is_stateless<decltype(f1), int>::value, "");
int j = 0;
auto f2 = [=](int i){ return i + j; };
static_assert(!is_stateless<decltype(f2), int>::value, "");
static_assert(is_stateless<std::vector<int>& (*) (std::vector<int>&, int, char, bool), std::vector<int>&, int, char, bool>::value, "");
static_assert(!is_stateless<std::vector<int>& (*) (std::vector<int>&, int, char, bool)>::value, "");
static_assert(!is_stateless<std::vector<int>& (*) (std::vector<int>&, int, char, bool), const std::vector<int>&, int, char, bool>::value, "");
}
Run Code Online (Sandbox Code Playgroud)