[ fromfile: functors.xml id: functors ]
Functors are generalized callable structures that can be invoked. Regular C and C++ functions, which readily convert to function pointers, fall into this category. Generic algorithms are typically overloaded to accept various categories of callables as parameters. Example 11.12 demonstrates how to invoke functions indirectly via function pointers.
Example 11.12. src/functors/pointers/main.cpp
#include <QtGui> QString name() { return QString("Alan"); } typedef QString (*funcPtr)(); Q_DECLARE_METATYPE(funcPtr); int main() { qRegisterMetaType<funcPtr>("funcPtr"); funcPtr ptr = name; QString v = (*ptr)(); qDebug() << v << endl; }
Pointers to functions are frequently used in C for callbacks, or functions that need to be called in response to certain events. In C++, it is possible to use object-oriented, template-based mechanisms as well. This way, you can specify the types of the arguments and return type at compile-time, making their use type-safe.
A functor in C++ is a callable object that behaves
like a function pointer, in the sense that it can be dereferenced and called like a function.
The C++ standard libs that comply with TR1[83] or later provide base class types for these in the <functional>
header file.
The C++ function call operator provides part of the syntactic sugar that makes objects act like functions.
The types std::unary_function
and std::binary_function
provide additional type information on C++ functors.
They are parameterized base class types you can extend, for use in QtAlgorithms, C++ STL and the Qt
Concurrent library.
Example 11.13, shows how to define functors
that can be used in places where function pointers are found.
Example 11.13. src/functors/operators/functors.h
[ . . . . ] class Load : public std::unary_function<QString, QImage> { public: QImage operator() (const QString& imageFileName) const { return QImage(imageFileName); } }; class Scale { public: typedef QImage result_type; QImage operator() (QImage image) const { for (int i=0; i<10; ++i) { QImage copy = image.copy(); copy.scaled(100, 100, Qt::KeepAspectRatio); } if (image.width() < image.height()) { return image.scaledToHeight(imageSize, Qt::SmoothTransformation); } else { return image.scaledToWidth(imageSize, Qt::SmoothTransformation); } } }; class LoadAndScale : public std::unary_function<QString, QImage> { public: Scale scale; QImage operator() (const QString& imageFileName) const { QImage image(imageFileName); return scale(image); } }; [ . . . . ]
In Example 11.14 a temporary instance of
LoadAndScale is created and passed to a QtConcurrent algorithm,
which is overloaded to accept function pointers and std::unary_function
objects
for its mapping function.
QtConcurrent is
discussed in more detail in Section 17.2.
Example 11.14. src/functors/operators/imagefunctor.cpp
[ . . . . ]
connect(m_futureWatcher, SIGNAL(progressValueChanged(int)),
this, SIGNAL(progressCurrent(int)));
emit statusMessage("Loading and Transforming in parallel");
m_futureWatcher->setFuture(QtConcurrent::mapped(files,
LoadAndScale()));
[83] C++ Technical Report 1 (TR1) is a draft document containing proposed additions to the C++ Standard Library that are likely to be included in the next official standard. See this Wikipedia article for more information.
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |