vc 2010 beta2 bind unique_ptr move

vc 2010 beta2 bind unique_ptr move

Post by nebojsa vu » Thu, 03 Dec 2009 20:55:00



Hello,

I'm playing with new language features and as a result:

win32 console app->empty project

file: main.cpp

#include <memory>
#include <functional>
#include <utility>

void foo(std::unique_ptr<int> pint)
{
}

int wmain( )
{
std::unique_ptr<int> pint(new int(42));
std::bind(foo, std::move(pint));
}


1>main.obj : error LNK2001: unresolved external symbol "public: __thiscall
std::unique_ptr<int,struct std::default_delete<int> >::unique_ptr<int,struct
std::default_delete<int> >(class std::unique_ptr<int,struct
std::default_delete<int> > const &)"
(??0?$unique_ptr@HU?$default_delete@H@std@@@std@@QAE@ABV01@@Z)

by analogy with:

#include <memory>
#include <utility>

void foo(std::unique_ptr<int> pint) { }

int wmain( )
{
std::unique_ptr<int> pint(new int(42));
foo(std::move(pint));
}

I expected that move constructor is called not copy constructor and I also
expected that move
constructor will be called when callee is invoked.

Will it be possible to transfer ownership to callee using bind, unique_ptr,
move combination ?
And does C++1x say anything about this or is it a VC bug or I expect too
much?

Thanks
 
 
 

vc 2010 beta2 bind unique_ptr move

Post by Igor Tande » Thu, 03 Dec 2009 22:41:05


The functional produced by std::bind stores a copy of pint (which it can do using move constructor). Its operator() would then call foo(copy_of_pint). It doesn't know enough about its parameter to infer that it should use move() in this call. So this is the part that fails.

The (draft) standard requires that parameters of std::bind be CopyConstructible, which unique_ptr isn't. So your program is invalid.


What led you to expect the latter?


Not as far as I can tell. Why would you need a functional that can be called only once?


Yes.


No.


Apparently.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925

 
 
 

vc 2010 beta2 bind unique_ptr move

Post by nebojsa vu » Fri, 04 Dec 2009 06:08:42


actually std::thread constructor led me to that

std::thread uses similar mechanism as bind, and it will be possible to
transfer ownership using:

std::thread thr(foo, std::move(pint));
where pint is instance of unique_ptr<int>

and I still think that this should be same as:

std::thread thr(std::bind(foo, std::move(pint)));

because there will have another:

Imperfection XXX:

in thread construction for most generic implementation don't use bind
although it may work now it will not work in all cases.

so I was convinced that rules for bind got somehow relaxed, or at least
has unique_ptr specialization.



Igor thank you for clearing this
 
 
 

vc 2010 beta2 bind unique_ptr move

Post by Igor Tande » Fri, 04 Dec 2009 06:58:18


That constructor is explicitly documented to support MoveConstructible arguments. The reason for the difference, I presume, is because thread is known to call its function object exactly once.


bind doesn't know that it's going to be called only once.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
 
 
 

vc 2010 beta2 bind unique_ptr move

Post by nebojsa vu » Fri, 04 Dec 2009 08:28:15


Although mechanics std::thread constructor and std::bind is similar, now
when you say it, yes contexts and definitely the purposes of std::bind
and std::thread are different. I'm no longer convinced that
specialization of std::bind for std::unique_ptr just for sake of
mimicking same behavior is a good idea.

Thank you again