Python -> C++ 习语:将 lambda 表达式存储在映射/容器中
Python -> C++ idiom: Storing lambda expressions in a map/container
我正在学习C (通过QT4)利用我的python/pyqt4体验,我似乎无法掌握将lambda表达式存储到容器中的适当习惯,以用作呼叫。<</p>我有一个带有许多字段的结构。我想创建一个可以正确格式化字段的回调图。
这是我想做的等同的python:
from PyQt4.QtCore import QVariant, QString
class AType(object):
def __init__(self):
self.name = "FOO"
self.attr2 = "BAR"
self.attr3 = "BAZ"
# ...
callbacks = {}
callbacks['name'] = lambda x: QVariant(QString(x.name))
callbacks['attr2'] = lambda x: QVariant(QString(x.attr2))
callbacks['attr3'] = lambda x: QVariant(QString(x.attr3))
a = AType()
variant = callbacks['name'](a)
print variant.toString()
# PyQt4.QtCore.QString(u'FOO')
起初,我在C 中找到了本机lambdas,然后开始尝试,但随后发现它显然是C 11功能。编辑:我想知道是否有C 11方法,然后才开始研究是否可以将标志引入项目的构建系统。
然后我看了增强解决方案。我的项目已经在使用Boost,所以我认为这可能是一个解决方案。我看到有lambda
和Phoenix
选项。为了表明我至少试图做这项工作,这是我令人尴尬的失败:
## my_class.h ##
#include <QVariant>
#include <QMap>
#include <boost/function.hpp>
QMap< uint, boost::function<QVariant (AType&)> > callbacks;
## my_class.cpp ##
#include <boost/lambda/lambda.hpp>
#include <boost/bind/bind.hpp>
#include "my_class.h"
// I invite you to laugh at this
callbacks[0] = boost::bind(&QVariant, boost::bind(&QString::fromStdString, boost::bind(&AType::name, _1)));
我写了最后一行后,我意识到自己正在旋转车轮,最好问更多的经验C 开发人员有关创建Lambda回调映射的惯用方法(与QT兼容)。
。我的目标是能够采用已知索引和已知的AType
实例,并能够返回适当的格式QVariant
更新
这是我发现的解决方案,基于公认的答案。使用C 98兼容解决方案。
#include <QMap>
#include <QVariant>
#include <QString>
#include <QDebug>
struct AType {
AType();
std::string name, attr2, attr3;
};
AType::AType() {
name = "FOO";
attr2 = "BAR";
attr3 = "BAZ";
}
typedef QMap< QString, QVariant (*)( AType const& ) > Callbacks;
struct ATypeFieldMapper
{
static QVariant name( AType const& x )
{ return QVariant(QString::fromStdString(x.name)); }
static QVariant attr2( AType const& x )
{ return QVariant(QString::fromStdString(x.attr2)); }
static QVariant attr3( AType const& x )
{ return QVariant(QString::fromStdString(x.attr3)); }
};
int main()
{
Callbacks callbacks;
callbacks["name"] = &ATypeFieldMapper::name;
callbacks["attr2"] = &ATypeFieldMapper::attr2;
callbacks["attr3"] = &ATypeFieldMapper::attr3;
AType a;
qDebug() << callbacks["name"](a).toString();
qDebug() << callbacks["attr2"](a).toString();
qDebug() << callbacks["attr3"](a).toString();
}
//"FOO"
//"BAR"
//"BAZ"
在c 中,lambda不过是句法糖,它允许您在内联编写函数定义。A foundor 是具有operator()
的对象。因此,如果您不能使用C 11(原因之一可能是因为您被迫使用旧编译器吗?),那么您总是可以只定义函数类,或者这些概念上的lambdas没有捕获任何东西,那么您只能使用普通旧功能。
: - )
凯,我要写一个示例。仅几分钟...
这里&hellip;
struct QString{ QString( wchar_t const* ){} };
struct QVariant { QVariant( QString const& ) {} };
struct AType{ wchar_t const* name() const { return L""; } };
#include <functional> // std::function
#include <map> // std::map
#include <string> // std::wstring
using namespace std;
void cpp11()
{
typedef map< wstring, function< QVariant( AType const& ) > > Callbacks;
Callbacks callbacks;
callbacks[L"name"] = []( AType const& x )
{ return QVariant( QString( x.name() ) ); };
auto const a = AType();
auto variant = callbacks[L"name"]( a );
}
void cpp03Limited()
{
typedef map< wstring, QVariant (*)( AType const& ) > Callbacks;
Callbacks callbacks;
struct SimpleConversion
{
static QVariant convert( AType const& x )
{ return QVariant( QString( x.name() ) ); }
};
callbacks[L"name"] = &SimpleConversion::convert;
AType const a = AType();
QVariant const variant = callbacks[L"name"]( a );
}
void cpp03General()
{
struct IConversion
{
virtual QVariant convert( AType const& ) const = 0;
};
struct ConversionInvoker
{
IConversion const* pConverter;
QVariant operator()( AType const& x ) const
{
return pConverter->convert( x );
}
explicit ConversionInvoker( IConversion const* const p = 0 )
: pConverter( p )
{}
};
typedef map< wstring, ConversionInvoker > Callbacks;
Callbacks callbacks;
struct SimpleConversion: IConversion
{
virtual QVariant convert( AType const& x ) const
{ return QVariant( QString( x.name() ) ); }
};
SimpleConversion const simpleConversionFunc;
callbacks[L"name"] = ConversionInvoker( &simpleConversionFunc );
AType const a = AType();
QVariant const variant = callbacks[L"name"]( a );
}
int main()
{}
免责声明:未经测试的代码(除了它使用MSVC和Mingw G 编译)。
相关文章:
- 将字符串存储在c++中的稳定内存中
- std::原子加载和存储都需要吗
- (C++)分析树以计算返回错误值的简单算术表达式
- C++:将控制台输出存储在宏中更好吗
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 提升精神:解析布尔表达式并简化为规范范式
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 使用正则表达式regex_search在字符串中查找字符串
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 如果不在内存中,则在哪里存储表达式和常数
- C++ 时间存储time_point表达式必须是可修改的左值
- Python -> C++ 习语:将 lambda 表达式存储在映射/容器中
- 如何将正则表达式模式存储为正则表达式对象或字符串
- 存储表达式的最佳实践
- 如何在C++11中将lambda表达式存储为类的字段
- 存储前缀表达式(递归)
- 将正则表达式存储在变量(std::string)中
- ' const int a = 1; '是' a '一个常量表达式,如果' a '具有自动存储持续时间
- 存储在vector中的表达式的延迟求值