mercredi 29 avril 2015

C++11 std::thread accepting function with rvalue parameter

I have some homework, and I have troubles understanding, (probably) how passing parameters to std::thread constructor works.

Assume following code (I deleted unneeded parts)

template<typename T, typename Task>
class Scheduler
{
    private:
        typedef std::unordered_map<std::size_t, T> Results;
        class Solver
        {
            public:
            Solver(Task&& task) : m_thread(&Solver::thread_function, std::move(task))
            {
                m_thread.detach();
            }

            Solver(Solver&& solver) = default; // required for vector::emplace_back
            ~Solver() = default;

            private:
            void thread_function(Task&& task)
            {
                task();
            }
            std::thread m_thread;
        };

    public:
        Scheduler() = default;
        ~Scheduler() = default;

        void add_task(Task&& task)
        {
            m_solvers.emplace_back(std::move(task));
        }

    private:
        std::vector<Solver> m_solvers;
};

template<typename T>
struct Ftor
{
    explicit Ftor(const T& t) : data(t) { }
    T operator()() { std::cout << "Computed" << std::endl; return data; }
    T data;
};

int main()
{
    Scheduler<int, Ftor<int>> scheduler_ftor;
    Scheduler<int, std::function<int(void)>> scheduler_lambda;
    Ftor<int> s(5);
    scheduler_ftor.add_task(std::move(s));
    scheduler_lambda.add_task([](){ std::cout << "Computed" << std::endl; return 1; });
}

Why it doesn't compile? MVS2015 is complaining about

functional(1195): error C2064: term does not evaluate to a function taking 1 arguments functional(1195): note: class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments
note: while compiling class template member function 'Scheduler<int,Ftor<int> >::Solver::Solver(Task &&)'

While G++ 4.9.2

functional: In instantiation of ‘struct std::_Bind_simple<std::_Mem_fn<void (Scheduler<int, Ftor<int> >::Solver::*)(Ftor<int>&&)>(Ftor<int>)>’:
required from ‘void Scheduler<T, Task>::add_task(Task&&) [with T = int; Task = Ftor<int>]’

functional:1665:61: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (Scheduler<int, Ftor<int> >::Solver::*)(Ftor<int>&&)>(Ftor<int>)>’ typedef typename result_of<_Callable(_Args...)>::type result_type;

I suppose there are some problems with std::moving to std::thread.

Aucun commentaire:

Enregistrer un commentaire