c++ - SFINAE,是可调用的特征

标签 c++ c++11 sfinae

我正在尝试实现一个小的 is_callable 特性来改进我自己。但是我遇到了一个小问题。当我尝试将仿函数与参数(或 lambda)一起使用时,问题就来了。 我没有弄清楚如何传递参数类型,或者如何自动推断它们……这是我的代码和结果:

#include <iostream>
#include <type_traits>
#include <cstdlib>



template<typename T, typename = void>
struct is_callable_impl : std::false_type {};

template<typename R, typename ...Args>
struct is_callable_impl<R(Args...), std::void_t <R(Args...)>> : std::true_type {};

template<typename Fn>
struct is_callable_impl < Fn, std::void_t<decltype(std::declval<Fn>()())>> : std::true_type{};

struct fonctor {
    void operator()() {}
};

struct fonctor2 {
    void operator()(double) {}
};

int fonct();
int fonct2(double);


int main() {
    auto l = [](float) {return false; };
    auto l2 = [&l] {return true; };
    std::cout << "expr" << std::endl;
    std::cout << is_callable_impl<double()>::value << std::endl; //write 1
    std::cout << is_callable_impl<int(int)>::value << std::endl; // write 1
    std::cout << is_callable_impl<void(double)>::value << std::endl;// write 1
    std::cout << is_callable_impl<void(double, int)>::value << std::endl; // write 1

    std::cout << "lambda" << std::endl;
    std::cout << is_callable_impl<decltype(l)>::value << std::endl;// write 0
    std::cout << is_callable_impl<decltype(l2)>::value << std::endl;// write 1

    std::cout << "function" << std::endl;
    std::cout << is_callable_impl<decltype(fonct)>::value << std::endl;// write 1
    std::cout << is_callable_impl<decltype(fonct2)>::value << std::endl;// write 1

    std::cout << "functors" << std::endl;
    std::cout << is_callable_impl<fonctor>::value << std::endl; // write 1
    std::cout << is_callable_impl<fonctor2>::value << std::endl; // write 0

    std::cout << "uncalled type" << std::endl;
    std::cout << is_callable_impl<int>::value << std::endl;// write 0

    system("pause");
    return 0;
}

最佳答案

好的,我测试了另一个想法。使用 std::is_function 可以检测对象是函数还是表达式。 之后,您只需要检查 operator= 是否存在。但是,当仿函数重载了 operator() 函数时,我的实现不起作用。

template<typename T, typename AlwaysVoid = void>
struct is_callable_impl : std::false_type {};

template<typename F>
struct is_callable_impl < F, std::enable_if_t < std::is_function<F>{}>> // Expression and Functions
    : std::true_type {};

// Lambda and functor
template<typename F>
struct is_callable_impl < F, std::void_t<std::enable_if_t < !std::is_function<F>{} >, decltype(&F::operator())>> : std::true_type{};

关于c++ - SFINAE,是可调用的特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47025617/

相关文章:

c++ - 在 C++ 中使用 vector 的矩阵运算导致段错误

c++ - 编译器会删除始终计算为零的 If block 吗?

c++ - 我可以信任 ceil() 结果的实数到整数的转换吗?

c++ - 创建一个变量来保存不同类型的对象 C++

C++ SFINAE - std::is_arithmetic 和 std::is_same 之间的分辨率优先级

C++ 服务器程序 Print While Loop

c++ - 映射值类型的decltype?

c++ - constexpr end istream (sentinel) 迭代器有什么意义?

C++ 友元函数模板重载和 SFINAE 在 clang++、g++、vc++(C++14 模式)中的不同行为

c++ - SFINAE 重载,必须考虑哪些规则