Python/pyqt4 の経験を活用して (Qt4 経由で) C++ を学習していますが、ラムダ式をコンテナーに格納してコールバックとして使用するための適切なイディオムを把握できないようです。
たくさんのフィールドを持つ構造体があります。そして、フィールドを特定の方法で適切にフォーマットできるコールバックのマップを作成したいと考えています。
これが私がやりたいことと同等の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++ のネイティブ ラムダを見つけて試してみましたが、明らかに C++11 の機能であることがわかりました。編集:プロジェクトのビルドシステムにフラグを導入できるかどうかを調査する前に、C++11 より前のアプローチがあるかどうかを知りたいです。
次に、ブーストソリューションを見ました。私のプロジェクトはすでにブーストを使用しているので、それが解決策になると思いました。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)));
最後の行を書いた後、自分が車輪を回転させていることに気付きました。ラムダ コールバックのマップ (Qt と互換性があります) を作成するための慣用的なアプローチについて、経験豊富な C++ 開発者に尋ねたほうがよいでしょう。
私の目標は、既知のインデックスと既知の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"