lambda的运算符重载
Operator overloading for lambdas?
在重载lambda
操作符>>之前,我问过一个类似的问题但我没有解释我真正想要的是什么。
我正在写一个简单的包装围绕sqlite3 C api。
这是我在github上的项目=> sqlite modern cpp
我想重载lambda的>>操作符。
我想要下面的代码工作:
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
类,它由'<<'运算符返回,我想能够重载>>操作符在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;
});
您需要的是回顾性的强制转换。一种通过只传递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的返回类型并写下面的
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; });
}
基于这个问题我写了下面的代码:
我没有完全理解function_traits
!但我做到了重载具有不同数量参数的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; };
}
相关文章:
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 重载运算符new[]的行为取决于析构函数
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 在 myVector 类中重载运算符 + 时出错
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 如何在 cpp 中重载运算符 +=?
- C++ 如何重载 [] 运算符并进行函数调用
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 重载运算符有地址吗?
- 如何迭代重载运算符 [] 的类?
- 重载运算符与添加问题
- 模板基类中的重载运算符
- 如何调用用于重载运算符"<<"的 friend 函数?
- 在 C++17 中的命名空间和子命名空间中重载运算符是不明确的
- 重载运算符<<采用谷歌 C++ 风格
- C++ 如何正确重载 + 运算符
- cout (<<) 重载运算符不打印减去的矩阵
- 如何在 c++ 中重载运算符 + 以便能够 whrite c_str = "smth" + c_str;
- 重载运算符*以获取对另一个类的实例的引用