Bug 42201 - [C++0x] std::vector<std::unique_future<T>>::push_back fails
Summary: [C++0x] std::vector<std::unique_future<T>>::push_back fails
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: 4.5.0
Assignee: Jonathan Wakely
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-11-27 21:37 UTC by Jack Lloyd
Modified: 2010-01-21 00:06 UTC (History)
2 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2009-11-27 23:08:12


Attachments
Test case (193 bytes, text/plain)
2009-11-27 21:39 UTC, Jack Lloyd
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jack Lloyd 2009-11-27 21:37:53 UTC
For reasons I do not fully understand, std::vector<std::unique_future<T>>'s push_back fails because it attempts to use the (deleted) copy constructor and (copying) assignment operator. The std::vector implementation seems to support move-only objects in C++0x mode, and I don't really see why that is not working here.

$ g++-4.5-20091112 -v
Using built-in specs.
COLLECT_GCC=/usr/local/bin/g++-4.5-20091112
COLLECT_LTO_WRAPPER=/usr/local/gcc-4.5-20091112/libexec/gcc/x86_64-unknown-linux-gnu/4.5.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.5-20091112/configure --prefix=/usr/local/gcc-4.5-20091112 --program-suffix=-4.5-20091112 --enable-languages=c,c++
Thread model: posix
gcc version 4.5.0 20091112 (experimental) (GCC)
Comment 1 Jack Lloyd 2009-11-27 21:39:08 UTC
Created attachment 19165 [details]
Test case

Here is the full output compiling this on my machine:

$ g++-4.5-20091112 -Wall -W -std=c++0x movable.cpp -o move
In file included from /usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/vector:69:0,
                 from movable.cpp:1:
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/future: In member function 'void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {std::unique_future<int>}, _Tp = std::unique_future<int>, _Alloc = std::allocator<std::unique_future<int> >, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<std::unique_future<int>*, std::vector<std::unique_future<int> > >, typename std::vector<_Tp, _Alloc>::_Base::_Tp_alloc_type::pointer = std::unique_future<int>*]':
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/vector.tcc:100:4:   instantiated from 'void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::unique_future<int>}, _Tp = std::unique_future<int>, _Alloc = std::allocator<std::unique_future<int> >]'
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/stl_vector.h:747:9:   instantiated from 'void std::vector<_Tp, _Alloc>::push_back(value_type&&) [with _Tp = std::unique_future<int>, _Alloc = std::allocator<std::unique_future<int> >, value_type = std::unique_future<int>]'
movable.cpp:12:50:   instantiated from here
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/future:440:22: error: deleted function 'std::unique_future<_Res>& std::unique_future<_Res>::operator=(const std::unique_future<_Res>&) [with _Res = int]'
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/vector.tcc:314:4: error: used here
In file included from /usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/vector:61:0,
                 from movable.cpp:1:
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/future: In static member function 'static _BI2 std::__copy_move_backward<true, false, std::random_access_iterator_tag>::__copy_move_b(_BI1, _BI1, _BI2) [with _BI1 = std::unique_future<int>*, _BI2 = std::unique_future<int>*]':
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/stl_algobase.h:596:18:   instantiated from '_BI2 std::__copy_move_backward_a(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = std::unique_future<int>*, _BI2 = std::unique_future<int>*]'
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/stl_algobase.h:606:45:   instantiated from '_BI2 std::__copy_move_backward_a2(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = std::unique_future<int>*, _BI2 = std::unique_future<int>*]'
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/stl_algobase.h:677:56:   instantiated from '_BI2 std::move_backward(_BI1, _BI1, _BI2) [with _BI1 = std::unique_future<int>*, _BI2 = std::unique_future<int>*]'
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/vector.tcc:308:4:   instantiated from 'void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {std::unique_future<int>}, _Tp = std::unique_future<int>, _Alloc = std::allocator<std::unique_future<int> >, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<std::unique_future<int>*, std::vector<std::unique_future<int> > >, typename std::vector<_Tp, _Alloc>::_Base::_Tp_alloc_type::pointer = std::unique_future<int>*]'
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/vector.tcc:100:4:   instantiated from 'void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::unique_future<int>}, _Tp = std::unique_future<int>, _Alloc = std::allocator<std::unique_future<int> >]'
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/stl_vector.h:747:9:   instantiated from 'void std::vector<_Tp, _Alloc>::push_back(value_type&&) [with _Tp = std::unique_future<int>, _Alloc = std::allocator<std::unique_future<int> >, value_type = std::unique_future<int>]'
movable.cpp:12:50:   instantiated from here
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/future:440:22: error: deleted function 'std::unique_future<_Res>& std::unique_future<_Res>::operator=(const std::unique_future<_Res>&) [with _Res = int]'
/usr/local/gcc-4.5-20091112/lib/gcc/x86_64-unknown-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/stl_algobase.h:561:6: error: used here
Comment 2 Paolo Carlini 2009-11-27 23:08:11 UTC
The issue is pretty simple, actually: std::unique_future (which, by the way, will be renamed just std::future), is missing move assignment operator. Note, in N2914 it does *not* exist, has been added only in N3000, I guess we can as well add it right now, before the rename. But again, consider that these facilities are still experimental, the working draft is changing rather quickly...
Comment 3 Jonathan Wakely 2009-11-30 10:38:56 UTC
(In reply to comment #2)
> The issue is pretty simple, actually: std::unique_future (which, by the way,
> will be renamed just std::future), is missing move assignment operator. Note,
> in N2914 it does *not* exist, has been added only in N3000, I guess we can as
> well add it right now, before the rename. But again, consider that these
> facilities are still experimental, the working draft is changing rather
> quickly...

I've already done most of the changes to update <future> to n3000, including adding move assignment, I just need to adjust the tests because lots of the old behaviour that was tested has changed (e.g. no default construction)

Comment 4 Paolo Carlini 2009-12-22 10:04:15 UTC
I think Jon can take this, for the std::future work.
Comment 5 Jonathan Wakely 2009-12-22 10:48:17 UTC
I'm planning to send a patch for feedback in the next 48 hours, including everything except atomic_future, because I think we need to implement [util.smartptr.shared.atomic] to support atomic_future
Comment 6 Paolo Carlini 2010-01-20 13:16:34 UTC
Jon, what do you think, shall we go ahead with this one too?
Comment 7 Jonathan Wakely 2010-01-20 14:38:05 UTC
I was going to ask you the same thing :-)

I would like to update <future> for 4.5, I'll send the patch when I get home in a few hours
Comment 8 Paolo Carlini 2010-01-20 14:46:17 UTC
Great.
Comment 9 Jonathan Wakely 2010-01-20 23:38:07 UTC
patch posted as http://gcc.gnu.org/ml/gcc-patches/2010-01/msg01126.html
Comment 10 Jonathan Wakely 2010-01-21 00:02:03 UTC
Subject: Bug 42201

Author: redi
Date: Thu Jan 21 00:01:47 2010
New Revision: 156097

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=156097
Log:
2010-01-21  Jonathan Wakely  <jwakely.gcc@gmail.com>

        PR libstdc++/42201
	* include/std/future: Update to latest WP.
	* src/functexcept.cc (__throw_future_error): Use make_error_code.
	* testsuite/30_threads/async/any.cc: New.
	* testsuite/30_threads/async/async.cc: New.
	* testsuite/30_threads/async/sync.cc: New.
	* testsuite/30_threads/packaged_task/cons/alloc.cc: New.
	* testsuite/30_threads/packaged_task/cons/assign_neg.cc: Adjust.
	* testsuite/30_threads/packaged_task/cons/copy_neg.cc: Adjust.
	* testsuite/30_threads/packaged_task/members/get_future.cc: Adjust.
	* testsuite/30_threads/packaged_task/members/get_future2.cc: Likewise.
	* testsuite/30_threads/packaged_task/members/invoke.cc: Adjust.
	* testsuite/30_threads/packaged_task/members/invoke2.cc: Adjust.
	* testsuite/30_threads/packaged_task/members/invoke3.cc: Adjust.
	* testsuite/30_threads/packaged_task/members/invoke4.cc: Adjust.
	* testsuite/30_threads/packaged_task/members/reset.cc: Adjust.
	* testsuite/30_threads/packaged_task/members/reset2.cc: Adjust.
	* testsuite/30_threads/shared_future/cons/assign_neg.cc: Remove.
	* testsuite/30_threads/shared_future/cons/default_neg.cc: Remove.
	* testsuite/30_threads/shared_future/cons/default.cc: New.
	* testsuite/30_threads/shared_future/cons/assign.cc: New.
	* testsuite/30_threads/shared_future/cons/copy.cc: Adjust.
	* testsuite/30_threads/shared_future/cons/move.cc: Adjust.
	* testsuite/30_threads/shared_future/cons/move_assign.cc: New.
	* testsuite/30_threads/shared_future/members/is_ready.cc: Remove.
	* testsuite/30_threads/shared_future/members/has_value.cc: Remove.
	* testsuite/30_threads/shared_future/members/has_exception.cc: Remove.
	* testsuite/30_threads/shared_future/members/valid.cc: New.
	* testsuite/30_threads/unique_future/cons/default_neg.cc: Remove.
	* testsuite/30_threads/unique_future/cons/default.cc: New.
	* testsuite/30_threads/unique_future/cons/move_assign.cc: New.
	* testsuite/30_threads/unique_future/cons/assign_neg.cc: Adjust.
	* testsuite/30_threads/unique_future/cons/copy_neg.cc: Adjust.
	* testsuite/30_threads/unique_future/cons/move.cc: Adjust.
	* testsuite/30_threads/unique_future/requirements/
        explicit_instantiation.cc: Adjust.
	* testsuite/30_threads/unique_future/members/is_ready.cc: Remove.
	* testsuite/30_threads/unique_future/members/has_value.cc: Remove.
	* testsuite/30_threads/unique_future/members/has_exception.cc: Remove.
	* testsuite/30_threads/unique_future/members/valid.cc: New.
	* testsuite/30_threads/unique_future/members/get.cc: Adjust.
	* testsuite/30_threads/unique_future/members/get2.cc: Adjust.
	* testsuite/30_threads/unique_future/members/wait.cc: Adjust.
	* testsuite/30_threads/unique_future/members/wait_for.cc: Adjust.
	* testsuite/30_threads/unique_future/members/wait_until.cc: Adjust.
	* testsuite/30_threads/headers/future/types_std_c++0x.cc: Adjust.
	* testsuite/30_threads/promise/cons/alloc.cc: New.
	* testsuite/30_threads/promise/cons/assign_neg.cc: Adjust.
	* testsuite/30_threads/promise/cons/copy_neg.cc: Adjust.
	* testsuite/30_threads/promise/cons/move.cc: Adjust.
	* testsuite/30_threads/promise/cons/move_assign.cc: Adjust.
	* testsuite/30_threads/promise/members/get_future.cc: Adjust.
	* testsuite/30_threads/promise/members/set_value.cc: Adjust.
	* testsuite/30_threads/promise/members/set_exception.cc: Adjust.
	* testsuite/30_threads/promise/members/set_exception2.cc: Adjust.
	* testsuite/30_threads/promise/members/set_value2.cc: Adjust.
	* testsuite/30_threads/promise/members/set_value3.cc: Adjust.
	* testsuite/30_threads/promise/members/swap.cc: Adjust.


Added:
    trunk/libstdc++-v3/testsuite/30_threads/async/
    trunk/libstdc++-v3/testsuite/30_threads/async/any.cc
    trunk/libstdc++-v3/testsuite/30_threads/async/async.cc
    trunk/libstdc++-v3/testsuite/30_threads/async/sync.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/cons/alloc.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/default.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/move_assign.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/valid.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/cons/default.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/cons/move_assign.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/members/valid.cc
Removed:
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/default_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/has_exception.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/has_value.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/is_ready.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/cons/default_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/members/has_exception.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/members/has_value.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/members/is_ready.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/std/future
    trunk/libstdc++-v3/src/functexcept.cc
    trunk/libstdc++-v3/testsuite/30_threads/headers/future/types_std_c++0x.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future2.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke2.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke3.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke4.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset2.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/cons/move.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/cons/move_assign.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/get_future.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_exception.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_exception2.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_value.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_value2.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_value3.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/swap.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/copy.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/move.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/cons/move.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/members/get.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/members/get2.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/members/wait.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/members/wait_for.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/members/wait_until.cc
    trunk/libstdc++-v3/testsuite/30_threads/unique_future/requirements/explicit_instantiation.cc

Comment 11 Jonathan Wakely 2010-01-21 00:06:32 UTC
Fixed.  The testcase works if you replace unique_future with future.