--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
I have been trying to use MakeUnique, but it's painful on classes
without a public constructor (as Dana mentions). Could we make it
easier for this to work without having to friend an internal function?
I have been trying to use MakeUnique, but it's painful on classes
without a public constructor (as Dana mentions). Could we make it
easier for this to work without having to friend an internal function?
That's the pattern I would like to work. Problem is the Create()
function isn't the one calling new, it's MakeUnique, which doesn't
have access to the private constructor.
As to Dana's comment about removing the Create() function and using
the constructor directly, there are cases where Create() does
additional work, may return null or a different implementation. You
can't capture that in a constructor.
On Wed, Aug 10, 2016 at 1:59 PM, Scott Violet <s...@chromium.org> wrote:I have been trying to use MakeUnique, but it's painful on classes
without a public constructor (as Dana mentions). Could we make it
easier for this to work without having to friend an internal function?Without knowing your particular scenario, I've been actively removing static Create() methods that return unique_ptrs and just exposing constructors publicly in src/cc/ lately, which both lets use use MakeUnique, and also lets us make classes direct members of owning class instead of separately-heap-allocated pointers.
- E
--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
---
You received this message because you are subscribed to the Google Groups "Chromium-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev+unsubscribe@chromium.org.
If MakeUnique is the recommended way, can someone update https://chromium.googlesource.com/chromium/src/+/master/third_party/WebKit/Source/wtf/UniquePtrTransitionGuide.md with the appropriate recommendations and caveats? I could write something, but I'm sure to get it wrong since I have to read this every time I change OwnPtr<T>'s.
So is a bulk CL changing WrapUnique(new Foo(...)) to MakeUnique<Foo>(...) wanted?
Shouldn't you be using nullptr instead of NULL anyway? :)
-Christian
An interesting issue is that NULL doesn't work in MakeUnique(). The type is inferred as long, which then can't be assigned to a pointer type. The obvious solution is to use nullptr.
I think this is probably a unique case as the magic of constant zero is not captured by the C++ type system.
On 12 August 2016 at 16:20, Peter Kasting <pkas...@chromium.org> wrote:On Fri, Aug 12, 2016 at 12:16 AM, Adam Rice <ri...@chromium.org> wrote:So is a bulk CL changing WrapUnique(new Foo(...)) to MakeUnique<Foo>(...) wanted?If it compiles, I would personally be in favor of it. But beware an automated change, since it can run into the problems mentioned already in this thread.PK
In a world where we still have private constructors, what is the preferred incantation?return std::unique_ptr<T>(new T());return base::WrapUnique(new T());...?Also... in a world where 'new' is anathema, how would we go about consing up ref counted types? Is make_refcounted a crazy thought?
In a world where we still have private constructors, what is the preferred incantation?return std::unique_ptr<T>(new T());return base::WrapUnique(new T());...?
I don't see the issue you're describing around MakeUnique; it should forward all arguments, including NULL, perfectly to the constructor.
--
That's because NULL gets type-deduced to long (since it's really just a macro for the integral constant zero), which doesn't convert to a pointer type. We should probably just s/NULL/nullptr/g in the codebase and be done with it.
I want to document what I've learned before I forget it, but I can't find a good place to do so, so I'm going to do it here.
I want to document what I've learned before I forget it, but I can't find a good place to do so, so I'm going to do it here.I would think one of the style guides would be a good place to capture many of those thoughts ;)
--
[sort-of off-topic] What _is_ the difference between WrapUnique(new Foo) and WrapUnique(new Foo()), out of interest..?
AIUI, if it's a POD type, the latter zero-initializes and the former doesn't.
-Christian
I suggest modifying the C++ Dos and Donts page to add an encouragement to use MakeUnique over bare new or WrapUnique, and then add info from the first two bullets (don't leave off () unless you really mean it, and if so, add a comment; don't friend MakeUnique).
> I'm not actually sure what the practical difference resulting from this rule change is.Pretty huge, when working with types that don't have a user-defined constructor. Here are some concrete examples:new char; // Pointer to an uninitialized charnew char(); // Pointer to a zero initialized char
--
I might be alone here, and I'm late to the party, but I still don't quite see the point of MakeUnique(). If you write C++, you'll have to understand new, and WrapUnique(new Foo(...)) is easy to understand. As this thread shows, MakeUnique() has a pretty long list of asterisks attached to it, without a benefit other than "no bare new" ¯\_(ツ)_/¯
Yes, it's unsafe to use WrapUnique with something allocated for operator new[]. However, WrapUnique can't distinguish between these cases because the return value is a pointer for non-array new and new[].
Daniel
CLs replacing a few thousand calls to WrapUnique() with MakeUnique() are now landed or under review.I want to document what I've learned before I forget it, but I can't find a good place to do so, so I'm going to do it here.
- WrapUnique(new Foo) and WrapUnique(new Foo()) mean something different if Foo does not have a user-defined constructor. I have not rewritten the first type of expression. Determining whether or not Foo has a user-defined constructor requires contextual information. For the sake of future maintainers, please use MakeUnique<Foo>() instead. If you're intentionally leaving off the "()" as an optimisation, please leave a comment.
- MakeUnique cannot be used to construct objects whose constructors are protected: or private:. Use WrapUnique() for these. Don't ever friend MakeUnique as this defeats the access control.
- The base:: namespace qualifier can be missed off WrapUnique if the object being wrapped is itself in base. I found this surprising. Use MakeUnique instead.
- NULL as an argument to MakeUnique doesn't work. Use nullptr instead.
- Constants that are passed to MakeUnique must have storage, so that they can be passed by reference. This can lead to linking errors when switching from WrapUnique to MakeUnique.
Future work:It seems thatfoo = MakeUnique<Foo>();is better modern C++ style thanfoo.reset(new Foo());
On Wednesday, August 24, 2016 at 4:06:12 AM UTC-6, Adam Rice wrote:CLs replacing a few thousand calls to WrapUnique() with MakeUnique() are now landed or under review.I want to document what I've learned before I forget it, but I can't find a good place to do so, so I'm going to do it here.
- WrapUnique(new Foo) and WrapUnique(new Foo()) mean something different if Foo does not have a user-defined constructor. I have not rewritten the first type of expression. Determining whether or not Foo has a user-defined constructor requires contextual information. For the sake of future maintainers, please use MakeUnique<Foo>() instead. If you're intentionally leaving off the "()" as an optimisation, please leave a comment.
- MakeUnique cannot be used to construct objects whose constructors are protected: or private:. Use WrapUnique() for these. Don't ever friend MakeUnique as this defeats the access control.
- The base:: namespace qualifier can be missed off WrapUnique if the object being wrapped is itself in base. I found this surprising. Use MakeUnique instead.
- NULL as an argument to MakeUnique doesn't work. Use nullptr instead.
- Constants that are passed to MakeUnique must have storage, so that they can be passed by reference. This can lead to linking errors when switching from WrapUnique to MakeUnique.
Future work:It seems thatfoo = MakeUnique<Foo>();is better modern C++ style thanfoo.reset(new Foo());The above came up in a code review today. Is this agreed on? It didn't seem to make it into the C++ do's and don'ts which only touches on WrapUnique. The other place this comes up is in an initializer list:: foo_ptr_(new Foo()),vs.: foo_ptr_(base::MakeUnique<Foo>()),Is there some reason to favor the latter?
On Wednesday, August 24, 2016 at 4:06:12 AM UTC-6, Adam Rice wrote:It seems thatfoo = MakeUnique<Foo>();is better modern C++ style thanfoo.reset(new Foo());The above came up in a code review today. Is this agreed on? It didn't seem to make it into the C++ do's and don'ts which only touches on WrapUnique. The other place this comes up is in an initializer list:: foo_ptr_(new Foo()),vs.: foo_ptr_(base::MakeUnique<Foo>()),Is there some reason to favor the latter?
The above came up in a code review today. Is this agreed on? It didn't seem to make it into the C++ do's and don'ts which only touches on WrapUnique. The other place this comes up is in an initializer list:: foo_ptr_(new Foo()),vs.: foo_ptr_(base::MakeUnique<Foo>()),Is there some reason to favor the latter?
--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
---
You received this message because you are subscribed to the Google Groups "Chromium-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev+unsubscribe@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-dev/19ad994c-2869-4234-a0ba-ab2a6937bf6c%40chromium.org.