I know we can't call std::future::get
many times, and we should use std::shared_future
if we need to call it many times.
But we can call boost::unique_future::get
many times, although there's boost::shared_future
!
void test1()
{
int i, j;
std::future<int> fu1 = std::async([]{ return 42; });
i = fu1.get();
//j = fu1.get(); // error occur
std::cout << i << std::endl;
boost::unique_future<int> fu2 = boost::async([]{ return 43; });
i = fu2.get();
j = fu2.get(); // sucess...?
std::cout << i << ' ' << j << std::endl;
std::cin.get();
}
The output is:
42
43 43
I thought for a moment and then try this test code.
class TestCls
{
public:
TestCls()
{
std::cout << "[TestCls] default constructor" << std::endl;
}
TestCls(const TestCls &other)
{
std::cout << "[TestCls] copy constructor" << std::endl;
}
TestCls(TestCls &&other)
{
std::cout << "[TestCls] move constructor" << std::endl;
}
TestCls &operator =(const TestCls &other)
{
std::cout << "[TestCls] copy assignment" << std::endl;
return *this;
}
TestCls &operator =(TestCls &&other)
{
std::cout << "[TestCls] move assignment" << std::endl;
return *this;
}
};
void test2()
{
TestCls a, b;
std::cout << std::endl << "unique_future test begin" << std::endl;
boost::unique_future<TestCls> fu1 = boost::async([]{ return TestCls(); });
fu1.wait();
std::cout << "first assignment" << std::endl;
a = fu1.get();
std::cout << "second assignment" << std::endl;
b = fu1.get();
std::cout << "unique_future test end" << std::endl;
std::cout << std::endl << "shared_future test begin" << std::endl;
boost::shared_future<TestCls> fu2 = boost::async([]{ return TestCls(); });
fu2.wait();
std::cout << "first assignment" << std::endl;
a = fu2.get();
std::cout << "second assignment" << std::endl;
b = fu2.get();
std::cout << "shared_future test end" << std::endl;
std::cin.get();
}
The output is:
[TestCls] default constructor
[TestCls] default constructor
unique_future test begin
[TestCls] default constructor
[TestCls] move constructor
first assignment
[TestCls] move constructor
[TestCls] move assignment
second assignment
[TestCls] move constructor
[TestCls] move assignment
unique_future test end
shared_future test begin
[TestCls] default constructor
[TestCls] move constructor
first assignment
[TestCls] copy assignment
second assignment
[TestCls] copy assignment
shared_future test end
Although boost::unique_future
do "move", not "copy", it is allowed to call get
many times.. How is it possible?
(My boost version is 1.55.0, and my compiler is VC++ 2013)
If I do #define BOOST_THREAD_VERSION 4
, an exception occurs at the second call of get()
. multiple call of get()
is undefined behavior until version 3? Or it's allowed until version 3?