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;
}
};
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;
}
};