Duwang
Duwang

Reputation: 301

In template, no type named type in "std::result_of<int&()>"

i am new to C++ programming, and am confused as to why i cannot supply my template parameters to intialise a packaged_task in cpp.

#include <vector>
#include <queue>
#include <chrono>
#include <thread>
#include <cassert>
#include <future>

using namespace std::chrono;
using std::future;
using std::packaged_task;
using std::priority_queue;

class CPlayGround {
    priority_queue<int> pq;

public:
    CPlayGround() {
        using task_type = int();
        packaged_task<task_type> pt{aFunc()};
    }

    int aFunc() {
        return 10;
    }
};

my CLion compiler states:

In template, no type named type in "std::result_of<int&()>"

Upvotes: 2

Views: 650

Answers (1)

Holt
Holt

Reputation: 37661

packaged_task wraps a callable object, if you pass aFunc(), you're passing the result of the call, which is an int, in your case it's the same as writing:

packaged_task<task_type> pt{10}; // does not make much sense, right?

If aFunc was a free function (not a member-function), you could pass its address to the packaged_task constructor:

packaged_task<task_type> pt{&aFunc};

But since it's a member function, the easiest-way1 is to wrap the call in a lambda:

packaged_task<task_type> pt{[this] { return aFunc(); }};

If you're not familiar with the syntax, [this] { return aFunc(); } is a lambda which captures this, takes no parameters (the () is optional for lambda) and whose body is as specified (we can access the member-function aFunc() because this is captured).

1 There are other ways, e.g. std::bind, but using a capturing lambda is what I would recommend in most cases.

Upvotes: 4

Related Questions