Quote Originally Posted by anda_skoa View Post
QtConcurrent::run() might be a bit weird to use when the function generates a result (usage of the QFuture API).
I concede that other QtConcurrent operations have a complicated way of returning results, but QtConcurrent::run() is actually fairly simple. Just set up a QFutureWatcher. When it emits finished(), you can immediately recover the result by calling result(). This is as simple as an asynchronous API can be (well, maybe a signal finished(T result) would be even simpler). A QThread-based solution will end up with a similar interface.

Quote Originally Posted by anda_skoa View Post
One also needs to be aware that the number of threads is limited, especially when using the overload that does not take a thread pool but uses the global instance.
Sure, but unless fine-grained control over the threads is required (which does not seem to be a primary concern of the OP), it makes sense to let QtConcurrent adapt the number of concurrent jobs to the actual capacity of the system.

Quote Originally Posted by anda_skoa View Post
And at least in one occasion I had a task not run in a separate thread. Not sure if that was a bug or something like work-stealing in case of an overloaded thread pool, I don't trust it to be run separately.
This probably is a bug; the documentation specifically mentions that the function is run in a separate thread.

In summary, this looks to me like the standard use case for QtConcurrent::run(): the OP just needs a high-level, concise API to run a task in a separate thread, and trusts the platform with the details of job management and scheduling.