我在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;
});
答案 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; };
}