c++compiler-errorspackaged-task

Error: cannot convert argument 1 from 'Packaged_Task::<class_name>' to 'std::nullptr_t'


The following program seems to be an error associated with an explicit constructor. However, I'm unable to find that out.

Using Visual Stduio 2017, the following error comes up on build:

C:/data/msvc/14.28.29333/include\future(475): error C2664: 'std::function<_Ret (int,int)>::function(std::nullptr_t) noexcept': cannot convert argument 1 from 'PackagedTask::SumUp' to 'std::nullptr_t'
        with
        [
            _Ret=int
        ]
C:/data/msvc/14.28.29333/include\future(475): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
C:/data/msvc/14.28.29333/include\functional(1158): note: see declaration of 'std::function<_Ret (int,int)>::function'
        with
        [
            _Ret=int
        ]
C:/data/msvc/14.28.29333/include\future(1348): note: see reference to function template instantiation 'std::_Packaged_state<_Ret (int,int)>::_Packaged_state<PackagedTask::SumUp&>(_Fty2)' being compiled
        with
        [
            _Ret=int,
            _Fty2=PackagedTask::SumUp &
        ]
C:/data/msvc/14.28.29333/include\future(1348): note: see reference to function template instantiation 'std::_Packaged_state<_Ret (int,int)>::_Packaged_state<PackagedTask::SumUp&>(_Fty2)' being compiled
        with
        [
            _Ret=int,
            _Fty2=PackagedTask::SumUp &
        ]
<source>(30): note: see reference to function template instantiation 'std::packaged_task<int (int,int)>::packaged_task<PackagedTask::SumUp&,0>(_Fty2)' being compiled
        with
        [
            _Fty2=PackagedTask::SumUp &
        ]
<source>(30): note: see reference to function template instantiation 'std::packaged_task<int (int,int)>::packaged_task<PackagedTask::SumUp&,0>(_Fty2)' being compiled
        with
        [
            _Fty2=PackagedTask::SumUp &
        ]
#include <future>
#include <iostream>
#include <deque>

using namespace std;

class PackagedTask {
private:
    // returns sum of numbers [begin, end)
    class SumUp {
        int operator()(int begin, int end) {
            cout << "SumUp(" << begin << ", " << end << ") ..." << endl;

            long long int sum{ 0 };

            for (int i{ begin }; i < end; i++) {
                sum += i;
            }

            return sum;
        }
    };

public:
    // static main method invoked from client
    static void main() {
        SumUp s1, s2, s3, s4;

        // wrap the tasks
        packaged_task<int(int, int)> task1(s1);
        packaged_task<int(int, int)> task2(s2);
        packaged_task<int(int, int)> task3(s3);
        packaged_task<int(int, int)> task4(s4);

        // create the futures
        future<int> res1 = task1.get_future();
        future<int> res2 = task2.get_future();
        future<int> res3 = task3.get_future();
        future<int> res4 = task4.get_future();

        // push tasks to deque (packaged tasks are not copyable)
        deque<packaged_task<int(int, int)>> tasks;
        tasks.push_back(move(task1));
        tasks.push_back(move(task2));
        tasks.push_back(move(task3));
        tasks.push_back(move(task4));

        int begin{ 1 };
        int inc{ 2500 };
        int end{ begin + inc };

        while (!tasks.empty()) {
            packaged_task<int(int, int)> cur_task = move(tasks.front());

            tasks.pop_front();

            thread sum_thread(move(cur_task), begin, end);

            begin = end;
            end += inc;

            sum_thread.join();
        }

        int sum = res1.get() + res2.get() + res3.get() + res4.get();

        cout << "Sum of 0 .. 10000 = " << sum << endl;
    }
};

Solution

  • packaged_task needs to be able to call SumUp::operator() so that needs to be public not private:

    class SumUp {
        public:
        int operator()(int begin, int end) {
            cout << "SumUp(" << begin << ", " << end << ") ..." << endl;
    
            long long int sum{ 0 };
    
            for (int i{ begin }; i < end; i++) {
                sum += i;
            }
    
            return sum;
        }
    };
    class SumUp {
        int operator()(int begin, int end) {
            cout << "SumUp(" << begin << ", " << end << ") ..." << endl;
    
            long long int sum{ 0 };
    
            for (int i{ begin }; i < end; i++) {
                sum += i;
            }
    
            return sum;
        }
    };