lundi 30 octobre 2017

SFINAE, is callable trait

I am trying to implement a little is_callable trait to improve mysel. However I am running a little issue. The issue comes when I am trying to use functor with arguments (or lambda). I did not figure out how pass the argument types, or how to deduce them automatically... Here is my code and the results :

#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;
}

Aucun commentaire:

Enregistrer un commentaire