<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Nov 21, 2013 at 3:57 PM, Nick Kledzik <span dir="ltr"><<a href="mailto:kledzik@apple.com" target="_blank">kledzik@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>Michael,</div><div><br></div>In lld, we have places that used nested a ErrorOr<std::unique_ptr<xx>> and I often hit compiler errors that require breaking up expressions to work around.   Do you have suggestions on how to code the following simple examples to not error?  Can some of these be fixed in ErrorOr.h?  Or am I totally not getting something?<div>
<br></div><div>-Nick<br><div><br></div><div><br><font face="Monaco" size="1">struct Foo { void doit(); };<br><br><br>std::unique_ptr<Foo> factoryU() {<br>  std::unique_ptr<Foo> f(new Foo);<br>  return f;  // works as expected<br>
}<br><br>ErrorOr<Foo*> factoryE() {<br>  ErrorOr<Foo*> f = new Foo;<br>  return f;  // works as expected<br>}<br><br>ErrorOr<std::unique_ptr<Foo>> factoryEU() {<br>  std::unique_ptr<Foo> f(new Foo);<br>
  return f; // ERROR: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<Foo, std::__1::default_delete<Foo> >’<br></font></div></div></div></blockquote><div><br></div><div>While a local variable inside a function is implicitly moved when returned, that only happens when the return expression is the local variable and the same type. In this case you have an implicit conversion that would work like any other conversion of an lvalue.<br>
<br>So you have to write return std::move(f); unfortunately. (or you could be more explicit/verbose and say return ErrorOr<...>(std::move(f)); )</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word"><div><div><font face="Monaco" size="1">}<br><br><br>void sinkU(std::unique_ptr<Foo> f) {<br>  f->doit();  // works as expected<br>}<br><br>void sinkE(ErrorOr<Foo*> f) {<br>
  f->doit(); // ERROR: member reference base type 'typename remove_reference<Foo *>::type' (aka 'Foo *') is not a structure or union'<br></font></div></div></div></blockquote><div><br>It's questionable whether this should work. ErrorOr<T> models a pointer to T. So if you had ErrorOr<Foo> f you'd expect to be able to do f->doit(), but if it's an ErrorOr<Foo*>, jsut like if it were a Foo**, you'd expect to have to use (*f)->doit().</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><font face="Monaco" size="1">}<br><br>void sinkEU(ErrorOr<std::unique_ptr<Foo>> f) {<br>
  f->doit(); // ERROR: no member named 'doit' in 'std::__1::unique_ptr<Foo, std::__1::default_delete<Foo> >'<br></font></div></div></div></blockquote><div><br></div><div>Same here.</div><div>
 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><font face="Monaco" size="1">}<br><br></font><br></div></div></div><br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br></blockquote></div><br></div></div>