#include <vector>
class B {
};
class A {
const std::vector<B> m_v;
public:
A(const std::vector<B>& v) : m_v(v) {}
void doSomething() {}
};
void foo(void* bar) {
A* a = (A*)bar;
a->doSomething();
}
int main() {
std::vector<B> v;
std::vector<A > l;
for (auto i = 0; i < 10; i++) {
A a(v);
l.push_back(std::move(a));
foo((void*)&l[i]);
}
return 0;
}
$ g++ -Wall initList.cpp -o initList -lrt -O3 -std=c++0x
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/vector:70:0,
from initList.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc: In member function \u2018void std::vector::_M_insert_aux(std::vector::iterator, _Args&& ...) [with _Args = {A}, _Tp = A, _Alloc = std::allocator, std::vector::iterator = __gnu_cxx::__normal_iterator >, typename std::_Vector_base::_Tp_alloc_type::pointer = A*]`:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:102:4: instantiated from \u2018void std::vector::emplace_back(_Args&& ...) [with _Args = {A}, _Tp = A, _Alloc = std::allocator]`
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_vector.h:840:9: instantiated from \u2018void std::vector::push_back(std::vector::value_type&&) [with _Tp = A, _Alloc = std::allocator, std::vector::value_type = A]`
initList.cpp:23:27: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:319:4: error: use of deleted function '& A::operator=(const A&)`
initList.cpp:6:7: error: '& A::operator=(const A&)` is implicitly deleted because the default definition would be ill-formed:
initList.cpp:6:7: error: passing \u2018const std::vector` as \u2018this` argument of \u2018std::vector& std::vector::operator=(const std::vector&) [with _Tp = B, _Alloc = std::allocator]` discards qualifiers [-fpermissive]
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/vector:61:0,
from initList.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h: In static member function \u2018static _BI2 std::__copy_move_backward::__copy_move_b(_BI1, _BI1, _BI2) [with _BI1 = A*, _BI2 = A*]`:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:581:18: instantiated from \u2018_BI2 std::__copy_move_backward_a(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = A*, _BI2 = A*]`
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:590:34: instantiated from \u2018_BI2 std::__copy_move_backward_a2(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = A*, _BI2 = A*]`
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:661:15: instantiated from \u2018_BI2 std::move_backward(_BI1, _BI1, _BI2) [with _BI1 = A*, _BI2 = A*]`
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:313:4: instantiated from \u2018void std::vector::_M_insert_aux(std::vector::iterator, _Args&& ...) [with _Args = {A}, _Tp = A, _Alloc = std::allocator, std::vector::iterator = __gnu_cxx::__normal_iterator >, typename std::_Vector_base::_Tp_alloc_type::pointer = A*]`
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:102:4: instantiated from \u2018void std::vector::emplace_back(_Args&& ...) [with _Args = {A}, _Tp = A, _Alloc = std::allocator]`
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_vector.h:840:9: instantiated from \u2018void std::vector::push_back(std::vector::value_type&&) [with _Tp = A, _Alloc = std::allocator, std::vector::value_type = A]`
initList.cpp:23:27: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:546:6: error: use of deleted function '& A::operator=(const A&)`
If I don't specify const for m_v. It compiles fine.
The error suggests something with assign operator, which I don't see how it is invoked.
Any idea?
Thanks in advance.
It's a bug in older versions of GCC/libstdc++, your code compiles fine with GCC 4.8.1. Live example. The bug is triggered by
l.push_back(std::move(a));
as older versions of GCC tried to create a default-constructed element in the vector and assigned the parameter std::move(a) to it in a second step instead of using the in-place copy/move-ctor.
Related
I have a strange compilation problem that I can't understand.
//I know, you should never derive from the STL Library
template<class T>
class SharedClass : private shared_ptr<T>
{
public:
template<class T2>
SharedClass(T2&& t2) :
shared_ptr<T>(make_shared<T>(move(t2)))
{}
virtual ~SharedClass()
{}
};
class A
{
public:
typedef function<void(SharedClass<A>)> Callback;
A(Callback callback)
{ }
};
main.cpp
SharedClass<A> shared([](SharedClass<A>){ });
Compile Log:
In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
from /usr/include/c++/7/bits/allocator.h:46,
from /usr/include/c++/7/string:41,
from /usr/include/c++/7/bits/locale_classes.h:40,
from /usr/include/c++/7/bits/ios_base.h:41,
from /usr/include/c++/7/ios:42,
from /usr/include/c++/7/ostream:38,
from /usr/include/c++/7/iostream:39,
from main.cpp:9:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = A; _Args = {SharedClass<A>}; _Tp = A]’:
/usr/include/c++/7/bits/alloc_traits.h:475:4: required from ‘static void std::allocator_traits<std::allocator<_CharT>>::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = A; _Args = {SharedClass<A>}; _Tp = A; std::allocator_traits<std::allocator<_CharT>>::allocator_type = std::allocator<A>]’
/usr/include/c++/7/bits/shared_ptr_base.h:526:39: required from ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {SharedClass<A>}; _Tp = A; _Alloc = std::allocator<A>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’ /usr/include/c++/7
/bits/shared_ptr_base.h:637:4: required from ‘std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = A; _Alloc = std::allocator<A>; _Args = {SharedClass<A>}; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:1295:35: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>; _Args = {SharedClass<A>}; _Tp = A; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr.h:344:64: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>; _Args = {SharedClass<A>}; _Tp = A]’
/usr/include/c++/7/bits/shared_ptr.h:690:14: [ skipping 9 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/c++/7/bits/shared_ptr_base.h:1295:35: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>; _Args = {main()::<lambda(SharedClass<A>)>}; _Tp = A; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr.h:344:64: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>; _Args = {main()::<lambda(SharedClass<A>)>}; _Tp = A]’ /usr/include/c++/7/bits/shared_ptr.h:690:14: required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = A; _Alloc = std::allocator<A>; _Args = {main()::<lambda(SharedClass<A>)>}]’
/usr/include/c++/7/bits/shared_ptr.h:706:39: required from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = A; _Args = {main()::<lambda(SharedClass<A>)>}]’
main.cpp:21:33: required from ‘SharedClass<T>::SharedClass(T2&&) [with T2 = main()::<lambda(SharedClass<A>)>; T = A]’
main.cpp:39:48: required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: no matching function for call to ‘A::A(SharedClass)’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:33:5: note: candidate: A::A(A::Callback)
A(Callback callback)
^ main.cpp:33:5: note: no known conversion for argument 1 from ‘SharedClass’ to ‘A::Callback {aka std::function)>}’
main.cpp:28:7: note: candidate: constexpr A::A(const A&)
class A
^ main.cpp:28:7: note: no known conversion for argument 1 from ‘SharedClass’ to ‘const A&’
main.cpp:28:7: note: candidate: constexpr A::A(A&&)
main.cpp:28:7: note: no known conversion for argument 1 from ‘SharedClass’ to ‘A&&’
If I change the constructor of the SharedClass class like this SharedClass (T2 t2) it compiles.
As your lambda takes its parameters by value it needs to be able to create copies of those parameters, it does this by calling the move constructor. As you have defined a templated constructor with the same signature as the move constructor the compiler attempts to use it as a move constructor. Adding default copy (for completeness) and move constructors fixes the issue:
SharedClass(const SharedClass&) = default;
SharedClass(SharedClass&&) = default;
Your existing constructor doesn't work as a move constructor because there is no constructor for A which takes a SharedClass<A> parameter so make_shared<A> doesn't compile when passed a SharedClass<A> parameter.
The following example complies in clang but fails in GCC.
Original link
Code:
#include<vector>
struct Foo
{
Foo() = default;
Foo(Foo&&) = default;
};
Foo baz(std::vector<Foo> foos);
Foo bar1(Foo&& foo_)
{
std::vector<Foo> foos{std::move(foo_)};
return baz(std::move(foos));
}
Foo bar2(Foo&& foo_)
{
std::vector<Foo> foos;
foos.push_back(std::move(foo_));
return baz(std::move(foos));
}
template<typename... Foos>
Foo bar3(Foo&& foo_, Foos&&... foos_)
{
std::vector<Foo> foos{std::move(foo_), std::forward<Foos>(foos_)...};
return baz(std::move(foos));
}
void dummy()
{
Foo f1, f2;
bar3(std::move(f1), std::move(f2));
}
Errors:
In file included from /opt/gcc-4.9.0/include/c++/4.9.0/vector:62:0,
from /tmp/gcc-explorer-compiler11512-1-c5m2m1/example.cpp:1:
/opt/gcc-4.9.0/include/c++/4.9.0/bits/stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = Foo; _Args = {const Foo&}]':
/opt/gcc-4.9.0/include/c++/4.9.0/bits/stl_uninitialized.h:75:53: required from 'static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const Foo*; _ForwardIterator = Foo*; bool _TrivialValueTypes = false]'
/opt/gcc-4.9.0/include/c++/4.9.0/bits/stl_uninitialized.h:125:41: required from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const Foo*; _ForwardIterator = Foo*]'
/opt/gcc-4.9.0/include/c++/4.9.0/bits/stl_uninitialized.h:278:63: required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = const Foo*; _ForwardIterator = Foo*; _Tp = Foo]'
/opt/gcc-4.9.0/include/c++/4.9.0/bits/stl_vector.h:1286:27: required from 'void std::vector<_Tp, _Alloc>::_M_range_initialize(_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const Foo*; _Tp = Foo; _Alloc = std::allocator<Foo>]'
/opt/gcc-4.9.0/include/c++/4.9.0/bits/stl_vector.h:378:36: required from 'std::vector<_Tp, _Alloc>::vector(std::initializer_list<_Tp>, const allocator_type&) [with _Tp = Foo; _Alloc = std::allocator<Foo>; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<Foo>]'
13 : required from here
/opt/gcc-4.9.0/include/c++/4.9.0/bits/stl_construct.h:75:7: error: use of deleted function 'constexpr Foo::Foo(const Foo&)'
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^
3 : note: 'constexpr Foo::Foo(const Foo&)' is implicitly declared as deleted because 'Foo' declares a move constructor or move assignment operator
struct Foo
^
Compilation failed
If it is a bug in GCC, can someone suggest an easy workaround for bar3 function?
It's not possible to move out of an initializer_list, so the corresponding constructor of std::vector has to copy. That's why you're getting the errors. bar2 should compile without errors.
The normal template pack expansion trick to repeatedly call push_back should work on the variadic version.
I have this minimal not-working example of code
#include <future>
int main()
{
auto intTask = std::packaged_task<int()>( []()->int{ return 5; } );
std::packaged_task<void()> voidTask{ std::move(intTask) };
}
Why doesn't it compile (on gcc 4.8.1)? I suspect, the reason is, that std::packaged_task stores the lambda internally inside an std::function which needs a CopyConstructible argument. However, std::packaged_task is move-only. Is this a bug? What does the standard say about it? In my opinion std::packaged_task should not need a CopyConstructible argument, but a MoveConstructible argument should be enough.
By the way, when I replace std::packaged_task<int()> by std::packaged_task<void()> everything compiles fine.
GCC 4.8.1 is giving me this error message:
In file included from /usr/include/c++/4.6/future:38:0,
from ../cpp11test/main.cpp:160:
/usr/include/c++/4.6/functional: In static member function 'static void std::_Function_base::_Base_manager<_Functor>::_M_clone(std::_Any_data&, const std::_Any_data&, std::false_type) [with _Functor = std::packaged_task<int()>, std::false_type = std::integral_constant<bool, false>]':
/usr/include/c++/4.6/functional:1652:8: instantiated from 'static bool std::_Function_base::_Base_manager<_Functor>::_M_manager(std::_Any_data&, const std::_Any_data&, std::_Manager_operation) [with _Functor = std::packaged_task<int()>]'
/usr/include/c++/4.6/functional:2149:6: instantiated from 'std::function<_Res(_ArgTypes ...)>::function(_Functor, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type) [with _Functor = std::packaged_task<int()>, _Res = void, _ArgTypes = {}, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type = std::function<void()>::_Useless]'
/usr/include/c++/4.6/bits/shared_ptr_base.h:410:4: instantiated from 'std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {std::packaged_task<int()>}, _Tp = std::__future_base::_Task_state<void()>, _Alloc = std::allocator<std::__future_base::_Task_state<void()> >, __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]'
/usr/include/c++/4.6/bits/shared_ptr_base.h:518:8: instantiated from 'std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = std::__future_base::_Task_state<void()>, _Alloc = std::allocator<std::__future_base::_Task_state<void()> >, _Args = {std::packaged_task<int()>}, __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]'
/usr/include/c++/4.6/bits/shared_ptr_base.h:987:35: instantiated from 'std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<std::__future_base::_Task_state<void()> >, _Args = {std::packaged_task<int()>}, _Tp = std::__future_base::_Task_state<void()>, __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]'
/usr/include/c++/4.6/bits/shared_ptr.h:317:64: instantiated from 'std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<std::__future_base::_Task_state<void()> >, _Args = {std::packaged_task<int()>}, _Tp = std::__future_base::_Task_state<void()>]'
/usr/include/c++/4.6/bits/shared_ptr.h:535:39: instantiated from 'std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = std::__future_base::_Task_state<void()>, _Alloc = std::allocator<std::__future_base::_Task_state<void()> >, _Args = {std::packaged_task<int()>}]'
/usr/include/c++/4.6/bits/shared_ptr.h:551:42: instantiated from 'std::shared_ptr<_Tp1> std::make_shared(_Args&& ...) [with _Tp = std::__future_base::_Task_state<void()>, _Args = {std::packaged_task<int()>}]'
/usr/include/c++/4.6/future:1223:66: instantiated from 'std::packaged_task<_Res(_ArgTypes ...)>::packaged_task(_Fn&&) [with _Fn = std::packaged_task<int()>, _Res = void, _ArgTypes = {}]'
../cpp11test/main.cpp:165:61: instantiated from here
/usr/include/c++/4.6/functional:1616:4: error: use of deleted function 'std::packaged_task<_Res(_ArgTypes ...)>::packaged_task(std::packaged_task<_Res(_ArgTypes ...)>&) [with _Res = int, _ArgTypes = {}, std::packaged_task<_Res(_ArgTypes ...)> = std::packaged_task<int()>]'
/usr/include/c++/4.6/future:1244:7: error: declared here
UPDATE: I have written the following test program. It seems to support the assumption that the reason is missing CopyConstructability. Again, what are the requirements on the type of the object from which an std::packaged_task may be constructed?
#include <future>
struct Functor {
Functor() {}
Functor( const Functor & ) {} // without this line it doesn't compile
Functor( Functor && ) {}
int operator()(){ return 5; }
};
int main() {
auto intTask = std::packaged_task<int()>( Functor{} );
}
Indeed, packaged_task only has a moving constructor (30.6.9/2):
template <class F> explicit packaged_task(F&& f);
However, your problem is the explicit constructor. So write it like this:
std::packaged_task<int()> pt([]() -> int { return 1; });
Complete example:
#include <future>
#include <thread>
int main()
{
std::packaged_task<int()> intTask([]() -> int { return 5; } );
auto f = intTask.get_future();
std::thread(std::move(intTask)).detach();
return f.get();
}
No. You just can't move a packaged_task<int ()> into a packaged_task<void ()>. These types a unrelated and cannot be move-assigned or move-constructed from each other. If you for some reason really want to do that you can "swallow" the result of the int () like this
The standard (as of N3690) doesn't state anything explicitly about the requirements of the type F in
template <class R, class... ArgTypes>
template <class F>
packaged_task<R(ArgTypes...)>::packaged_task(F&& f);
(see 30.6.9.1) However, it states that
Invoking a copy of f shall behave the same as invoking f.
and that this call can throw
any exceptions thrown by the copy or move constructor of f, or std::bad_alloc if memory
for the internal data structures could not be allocated.
This implicitly implies that the type F must be at least MoveConstructible, or CopyConstructible, if an lvalue reference is handed to the function.
Hence, it's not a bug, it's just not specified that precisely. To solve the problem of putting a std::packaged_task<int()> into a std::packaged_task<void()> just wrap the first into a shared_ptr like this:
#include <future>
#include <memory>
int main()
{
auto intTask = std::make_shared<std::packaged_task<int()>>(
[]()->int{ return 5; } );
std::packaged_task<void()> voidTask{ [=]{ (*intTask)(); } };
}
#include <functional>
#include <algorithm>
#include <list>
using namespace std;
struct foo{
int _val;
};
int main(){
list<foo> A;
foo B;
for(int i=0;i<10;++i){
B._val=i;
A.push_back(B);
}
list< reference_wrapper < foo > > C(A.begin(),A.end());
return 0;
}
I am trying to use std::reference_wrapper to hold references to type "foo" but when I do this I get a very peculiar compiler error:
>In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/list:63,
from ref_wrapper.cpp:4:/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_list.h: In member function \u2018void std::list<_Tp, _Alloc>::_M_initialize_dispatch(_InputIterator, _InputIterator, std::__false_type) [with _InputIterator = std::_List_iterator<foo>, _Tp = std::reference_wrapper<foo>, _Alloc = std::allocator<std::reference_wrapper<foo> >]\u2019:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_list.h:577: instantiated from \u2018std::list<_Tp, _Alloc>::list(_InputIterator, _InputIterator, const _Alloc&) [with _InputIterator = std::_List_iterator<foo>, _Tp = std::reference_wrapper<foo>, _Alloc = std::allocator<std::reference_wrapper<foo> >]\u2019
ref_wrapper.cpp:19: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_list.h:1361: error: no matching function for call to \u2018std::list<std::reference_wrapper<foo>, std::allocator<std::reference_wrapper<foo> > >::push_back(foo&)\u2019
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_list.h:919: note: candidates are: void std::list<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = std::reference_wrapper<foo>, _Alloc = std::allocator<std::reference_wrapper<foo> >]
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_list.h:924: note: void std::list<_Tp, _Alloc>::push_back(_Tp&&) [with _Tp = std::reference_wrapper<foo>, _Alloc = std::allocator<std::reference_wrapper<foo> >]
It is impossible to discern what is going on. I have tried the same code on VS 2010 and it worked. I am wondering why it's not working for g++
The command I entered in terminal was:
g++ -std=gnu++0x reference_wrapper_test.cpp -o reference_wrapper_test
I think that you could update your compiler .
See the Link : http://liveworkspace.org/code/3mVcGp$6
Could someone tell me why the following won't compile?
#include "a.h"
#include <list>
#include <algorithm>
#include <tr1/functional>
using namespace std;
class B {
public:
B() {
list< A* > aList;
A* a = new A();
lower_bound( aList.begin(), aList.end(), a, tr1::bind( &B::aComp, tr1::placeholders::_1, tr1::placeholders::_2 ) );
}
private:
bool aComp( A* a1, A* a2 );
};
Compile output:
In file included from c:\qt\2010.04\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/tr1/functional:56,
from ..\bindTest\/b.h:4,
from ..\bindTest\b.cpp:1:
c:\qt\2010.04\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/tr1_impl/functional: In member function 'typename std::tr1::result_of<_Functor(typename std::tr1::result_of<std::tr1::_Mu<_Bound_args, std::tr1::is_bind_expression::value, (std::tr1::is_placeholder::value > 0)>(_Bound_args, std::tr1::tuple<_UElements ...>)>::type ...)>::type std::tr1::_Bind<_Functor(_Bound_args ...)>::__call(const std::tr1::tuple<_UElements ...>&, std::tr1::_Index_tuple<_Indexes ...>) [with _Args = A*&, A* const&, int ..._Indexes = 0, 1, _Functor = std::tr1::_Mem_fn<bool (B::*)(A*, A*)>, _Bound_args = std::tr1::_Placeholder<1>, std::tr1::_Placeholder<2>]':
c:\qt\2010.04\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/tr1_impl/functional:1191: instantiated from 'typename std::tr1::result_of<_Functor(typename std::tr1::result_of<std::tr1::_Mu<_Bound_args, std::tr1::is_bind_expression::value, (std::tr1::is_placeholder::value > 0)>(_Bound_args, std::tr1::tuple<_UElements ...>)>::type ...)>::type std::tr1::_Bind<_Functor(_Bound_args ...)>::operator()(_Args& ...) [with _Args = A*, A* const, _Functor = std::tr1::_Mem_fn<bool (B::*)(A*, A*)>, _Bound_args = std::tr1::_Placeholder<1>, std::tr1::_Placeholder<2>]'
c:\qt\2010.04\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/bits/stl_algo.h:2495: instantiated from '_FIter std::lower_bound(_FIter, _FIter, const _Tp&, _Compare) [with _FIter = std::_List_iterator<A*>, _Tp = A*, _Compare = std::tr1::_Bind<std::tr1::_Mem_fn<bool (B::*)(A*, A*)>(std::tr1::_Placeholder<1>, std::tr1::_Placeholder<2>)>]'
..\bindTest\/b.h:13: instantiated from here
c:\qt\2010.04\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/tr1_impl/functional:1137: error: no match for call to '(std::tr1::_Mem_fn<bool (B::*)(A*, A*)>) (A*&, A* const&)'
c:\qt\2010.04\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/tr1_impl/functional:546: note: candidates are: _Res std::tr1::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class&, _ArgTypes ...) const [with _Res = bool, _Class = B, _ArgTypes = A*, A*]
c:\qt\2010.04\mingw\bin\../lib/gcc/mingw32/4.4.0/include/c++/tr1_impl/functional:551: note: _Res std::tr1::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class*, _ArgTypes ...) const [with _Res = bool, _Class = B, _ArgTypes = A*, A*]
aComp is a nonstatic member function of B, so you need to bind to the this pointer as well:
tr1::bind(&B::aComp, this, tr1::placeholders::_1, tr1::placeholders::_2)