- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在学习 C++(通过 Qt4)利用我的 python/pyqt4 经验,但我似乎无法掌握将 lambda 表达式存储到容器中以用作回调的正确习惯用法。
我有一个包含大量字段的结构。我想创建一个回调映射,可以以特定方式正确格式化字段。
这是我想做的 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++ 中发现了原生的 lambda 并开始尝试,但后来发现它显然是 C++11 的一个特性。 编辑:在开始调查是否可以将标志引入项目的构建系统之前,我想知道是否有 C++11 之前的方法。
然后我研究了 boost 解决方案。我的项目已经在使用 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 只不过是语法糖,它允许您内联编写仿函数定义。 仿函数 是一个带有operator()
的对象。所以如果你不能使用 C++11(一个原因可能是因为你被迫使用旧的编译器?)那么你总是可以只定义仿函数类,或者如果那些概念性的 lambdas 没有捕获任何东西,那么你可以只使用普通的旧函数。
:-)
凯,我要写一个例子。就几分钟...
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++ - Python -> C++ 习语 : Storing lambda expressions in a map/container,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13354729/
这个问题已经有答案了: What is the Java ?: operator called and what does it do? (17 个回答) 已关闭 8 年前。 ltVal = node
我是一名 Java 学生,我在嵌套该程序的条件语句时遇到问题 Exercise CozaLozaWoza (Loop & Condition): Write a program called Coza
首先,我想给出用户想要留下的句子的数量,当他的写作结束时,我的代码开始将每个单词的第一个字母大写(在 Java 中)。 import java.util.Scanner; public class I
我尝试在基类中实现一个函数,该函数使用子函数(defiend 作为基类中的抽象函数)。我认为一个例子可以最好地说明这个问题。 abstract class Animal{ public void
就像在口吃中一样,如果文本为“dean”并且乘数为 3,则结果将是“dddeeeaaannn”。 public static void repeatLetters() { String text
public void insert(int data) { if (root == null) root = new AVLNode(data); else {
我是 XPATH 的新手,并且遇到以下问题: 我有以下代码片段,但似乎无法按我的预期工作: String XML = cdataContent;
例如,Java 数据类型字节将数据从 -128 到 127 存储在单个字节中。为了能够区分 - 1 到 -128 从 0 到 127 将需要额外的数据,这些数据将采用数据类型覆盖其分配的存储空间。不可
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
Dataset: P1: Lion, Snow, Chair P2: Min: 0, Max: 28 P3: Min: 34, Max is 39. 我的程序 以一系列数组列表的形式提供上述数据集(P
我正在构建一个应该 24/7 全天候运行的客户端服务器应用程序。应用程序指定检测网络故障(使用心跳)并尽快重新连接到服务器。 我做的第一个测试只是停止客户端或服务器,然后重新启动,一切正常。我想知道是
我怀疑它是编写它的类的类型,但我不是 100% 确定,有人可以证实我的怀疑并可能提供对定义此行为的 Java 语言规范的引用吗? 假设类 A 有一个方法 a(),它在其主体中使用了 this 关键字,
我已经在谷歌上搜索了两个小时,但没有成功。 如果我有一个模板函数并且我想在模板类型上强制执行一个接口(interface),我该怎么做? 例如。 void doStuff(T)(bool param)
我正在尝试获取用户输入并对其进行修改,以便打印不带任何元音的字符串。我已经能够使用以下代码成功完成此操作。 Scanner in = new Scanner(System.in); Syste
每当我使用 Thread.sleep(); 时在 do while 循环中,提示告诉我,“在循环中调用 Thread.sleep 可能会导致性能问题。”我从许多其他网站和书籍上听到过这一点。我可以用什
请不要将其视为以下内容的重复项而将其忽略: How to generate random positive and negative numbers in java 我需要使用带有种子的随机数生成器。
我想在一个数字范围内选择随机数,但权重偏向该范围的一部分。例如: 选择1-10之间的随机数 对其进行加权,使 1-5 比 6-10 的可能性高 20% 这可能吗?我该怎么做? 最佳答案 这取决于您希望
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 8 年前。 Improve this ques
我有一个付款 Activity 和启动 Activity ,它在用户购买后显示内容应用程序。付款 Activity 是Manifest.xml中的默认启动器,我想将启动器 Activity 设置为启动
我有一个指针和长度。如何从他们那里得到一个动态数组? 最佳答案 设ptr是一个指针,len是一个长度,那么很容易如下: ptr[0..len] 请注意,这不会复制数组,而是就地使用数据。 如果要复制数
我是一名优秀的程序员,十分优秀!