运营商为lambdas超载?

时间:2014-05-11 16:16:06

标签: c++ c++11 lambda operator-overloading

我在overloading operator >> for lambdas之前问过类似的问题 但我没有解释我真正想要的东西。

我正在编写一个围绕sqlite3 C api的简单包装 this is my project on github => sqlite modern cpp

我想重载>> lambdas的操作员。
我希望以下代码能够正常工作:

database db("dbfile.db");
db << "select age,name,weight from user where age > ? ;"
   << 18
   >> [&](int age, string name, double weight) {
       cout << age << ' ' << name << ' ' << weight << endl;
   };

我想要这个主意!这就是为什么我在上一个问题中提出了这个问题。 我有一个database_bind类,由'&lt;&lt;'返回运营商 我希望能够超载&gt;&gt; database_bind上的算子 对于具有不同参数数量的lambda。

目前我支持这种语法:

db << "select age,name,weight from user where age > ? ;"
   << 18
   >> function<void(int,string,double)>([&](int age, string name, double weight) {
       cout << age << ' ' << name << ' ' << weight << endl;
   });

2 个答案:

答案 0 :(得分:0)

你需要的是一次回顾展。一种组合正确的函数对象类型的方法,只传递一个lambda(,没有别的,没有模板参数,没有返回类型规范)。

在没有其他库的依赖性的情况下执行此操作的方法如下:

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

然后你可以知道你的lambas&#39;返回类型并写下以下内容

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

答案 1 :(得分:-1)

基于this question 我写下了以下代码 我没有完全理解function_traits!但我能够 超载&gt;&gt; lambdas的运算符,具有不同数量的参数。 我知道这不是最好的解决方案,但是我写了它,所以有人可以把它作为一个起点(可变参数模板实现会很棒!)。

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

最后:

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