[Qt-creator] use of std::function in creator

Mohamed Fawzi Fawzi.Mohamed at digia.com
Mon Aug 19 14:13:29 CEST 2013


On 15 Aug 2013, at 21:12, André Pönitz <andre.poenitz at mathematik.tu-chemnitz.de> wrote:

> On Thu, Aug 15, 2013 at 04:33:52PM +0400, Konstantin Tokarev wrote:
>> 
>> 
>> 15.08.2013, 16:28, "Mohamed Fawzi" <Fawzi.Mohamed at digia.com>:
>>> Hi there were already discussions on using C++11, but I would like to
>>> use something that is a bit older.
>>> 
>>> std::function can be very useful to define callbacks, and thus
>>> improving the api very much.  It was already available as part of the
>>> technical report 1:
>>> 
>>> #include <tr1/functional>
>>> 
>>> std::tr1::function
>>> 
>>> windows released that in 2008, and gcc/clang should work even earlier.
>>> 
>>> libstdc++ support is not complete (custom allocator are not supported),
>>> but if I understand it correctly (you cannot pass custom allocators to
>>> the function type) it should be fine.
>>> 
>>> So with a couple of #ifdef and typedefs one could use it already.
>>> 
>>> What do other think?
>> 
>> Traditional Qt approach is to use singals and slots instead of callbacks.
> 
> Right. But that comes not for free, and there are situations where simpler
> means fit the bill, too.

Indeed, continuation passing style (using the callback to tell what to do next) in general any case in which you need different connections for every call (annoying to setup, and maybe requiring the allocation of different object to not clash with other signal invocations), or when you want to parametrize on the result of a function call are such examples.

Yes there are other solutions (signal and slots, superclasses defining virtual functions, using templates), still not having a generic easy way to pass in a function like object (function, functor, closure, anything as long it has a given signature), was always one of the things that annoyed me a lot in C++.
std::function solves that.

> If we have std::[tr1::]function on all the compilers we need to support,
> (and perhaps find a way to spell that with less pain on the eyes), 
> I am pretty much in favour.

// ------------------
#include <functional>
#if !(__cplusplus > 199711L || __GXX_EXPERIMENTAL_CXX0X__ || _MSC_VER >= 1600 || defined( _LIBCPP_VERSION ))
#define USE_TR1
#endif

#ifdef USE_TR1
#  ifdef __GNUC__
#    include <tr1/functional>
#  endif
namespace cpp11x = std::tr1;
#else
namespace cpp11x = std;
#endif
// ------------------

should work everywhere we care about.

With it for example the following code works.

Fawzi

// ------------------
void f(cpp11x::function<void(const QString&)> errorPrinter)
{
	errorPrinter(QLatin1String("bla"));
	errorPrinter(QString::fromLatin1("blaAgain"));
}

struct LogErrors {
	QStringList &loggedErrors;
	explicit LogErrors(QStringList &loggedErrors) : loggedErrors(loggedErrors) { }
	void operator()(const QString &s) {
		loggedErrors << s;
	}
};

void dLog(const QString &msg)
{
	qDebug() << msg;
}

int main(int argc, const char* argv[])
{
	QStringList l;
	f(&dLog);
	f(LogErrors(l));
	qDebug() << "logged errors:" << l;
}
// ------------------





More information about the Qt-creator mailing list