Operator overloading for lambdas?

后端 未结 2 1592
一整个雨季
一整个雨季 2020-12-19 20:53

I have asked a similar question before overloading operator >> for lambdas
But i did not explained what i really wanted .

I am writing a simple wrapper around

相关标签:
2条回答
  • 2020-12-19 21:04

    What you need is a retrospective cast. A way to compose a correct function object type from passing it only a lambda (and nothing else, no template arguments, not return type specification).

    A way to do it without dependencies from other libraries would be the following

    #include <iostream>
    #include<functional>
    #include<vector>
    
    
    using namespace std;
    
    
    template<typename T>
    struct memfun_type 
    {
        using type = void;
    };
    
    template<typename Ret, typename Class, typename... Args>
    struct memfun_type<Ret(Class::*)(Args...) const>
    {
        using type = std::function<Ret(Args...)>;
    };
    
    template<typename F>
    typename memfun_type<decltype(&F::operator())>::type
    FFL(F const &func) 
    { // Function from lambda !
        return func;
    }
    

    Then you can be aware of your lambas' return type and write the following

    int main() 
    {
        database_bind dbb;
    
        dbb >> FFL([](int i, string s) { cout << i << ' ' << s << endl; });
        dbb >> FFL([](int i) { cout << i << endl; });
        dbb >> FFL([](string s,double d) { cout << s << ' ' << d << endl; });
    }
    
    0 讨论(0)
  • 2020-12-19 21:13

    Based on this question i wrote the fallowing code.
    I did not completely understood function_traits ! but i was able to overload the >> operator for lambdas with different number of arguments . I know it's not the best possible solution , but i wrote it so someone can take it as a starting point ( a variadic template implementation will be awesome !) .

    #include<iostream>
    #include<string>
    #include<tuple>
    using namespace std;
    
    template <typename T>
    struct function_traits
    : public function_traits<decltype(&T::operator())>
    {};
    
    template <typename ClassType, typename ReturnType, typename... Args>
    struct function_traits<ReturnType(ClassType::*)(Args...) const>
    // we specialize for pointers to member function
    {
        enum { arity = sizeof...(Args) };
        // arity is the number of arguments.
    
        typedef ReturnType result_type;
    
        template <size_t i>
        struct arg
        {
            typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
            // the i-th argument is equivalent to the i-th tuple element of a tuple
            // composed of those arguments.
        };
    };
    
    // a place holder class
    class database_bind {};
    
    template<int N>
    class A {
        template<typename F>
        static void run(F l);
    };
    
    template<>
    struct A<1> {
        template<typename F>
        static void run(F l) {
            typedef function_traits<decltype(l)> traits;
            typedef typename traits::arg<0>::type type_1;
    
            type_1 col_1;
            get_from_db(0, col_1);
    
        l(col_1);
        }
    };
    template<>
    struct A<2> {
        template<typename F>
        static void run(F l) {
            typedef function_traits<decltype(l)> traits;
            typedef typename traits::arg<0>::type type_1;
            typedef typename traits::arg<1>::type type_2;
    
            type_1 col_1;
            type_2 col_2;
            get_from_db(0, col_1);
            get_from_db(1, col_2);
    
            l(col_1, col_2);
        }
    };
    
    
    void get_from_db(int col_inx, string& str) {  str = "string"; }
    void get_from_db(int col_inx, int& i) {i = 123;}
    void get_from_db(int col_inx, double& d) { d = 123.456; }
    
    
    template<typename F>
    void operator>>(database_bind dbb, F l)
    {
        typedef function_traits<decltype(l)> traits;
        A<traits::arity>::run(l);
    }
    

    And finally :

    int main() {
        database_bind dbb;
    
        dbb >> [](int i, string s) { cout << i << ' ' << s << endl; };
        dbb >> [](int i) { cout << i << endl; };
        dbb >> [](string s,double d) { cout << s << ' ' << d << endl; };
       }
    
    0 讨论(0)
提交回复
热议问题