I would use a std::set<std::unique_ptr<T>> as you suggest. Lookup can be done by std::find_if with a lambda.
--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To post to this group, send email to c...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CANh-dXkeUcf872KRx634Xj%3DMy_xuL8kTgO0PE4x%2BWoF96ZutAw%40mail.gmail.com.
http://stackoverflow.com/questions/17851088/using-a-stdunordered-set-of-stdunique-ptr
Has an interesting alternative -
std::map<DnsRequest*,std::unique_ptr<DnsRequest>>, raw pointer as key
and the value tagging along as owner.
Otherwise, that thread doesn't seem promising. There's a suggestion
to use a custom do-nothing deleter for your probe value, but that
seems brittle, at best.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAA0c_LOMF45aGA00HRzJaOBQ0yng6t4jtnhjz4kd6yr0YDeHvg%40mail.gmail.com.
> I would use a std::set<std::unique_ptr<T>> as you suggest. Lookup can be
> done by std::find_if with a lambda.
find_if() is linear while a good std::set lookup is logarithmic. C++14
added heterogenous lookups to std::sets (signatures 3 and 4 in
http://en.cppreference.com/w/cpp/container/set/find), but you have to
explicitly specify std::less<> (literally no arguments) as the
comparator. It's messy, and one reason to prefer writing our own
containers instead of using the STL's.
--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To post to this group, send email to c...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAAHOzFDDo3QCM8dM-g3P3gA71Kk-f_XtiKjMaymjPbWhyhE6cg%40mail.gmail.com.
I guess this is going to be an opinion kind of thing, but I personally map.find() easier to read than find_if(set, <lambda>).
I haven't been able to think of a good pattern to use here.Any thoughts?Thanks!Avi
--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To post to this group, send email to c...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/59a67309-43a5-492d-8c2c-677536b98038%40chromium.org.
On Mon, Aug 15, 2016 at 9:23 PM, Dmitry <dsk...@chromium.org> wrote:
On Sunday, August 14, 2016 at 1:53:09 PM UTC-7, Avi Drissman wrote:For fun I'm hacking away at http://crbug.com/555865, removing use of the STL* functions in favor of proper ownership with smart pointers.Some are easy; STLDeleteContainerPairSecondPointers is basically just rewriting maps to own their values.But I'm hitting a bit of a problem with STLDeleteContainerPairFirstPointers, STLDeleteContainerPointers, and STLDeleteElements. Often those are used with sets or maps with owned keys, where the owned item is being used for lookup.As a random example, look at P2PSocketDispatcherHost. It has a std::set of DnsRequest objects named dns_requests_, and that set owns the requests. As it creates the requests, it tossed them into the set, and as the requests resolve, it removes them from the set.How do you turn that into owned objects? Sure, you can say std::set<std::unique_ptr<DnsRequest>>, but how do you do a lookup of an item? You can't use the set's find, because you can't == a pointer and a unique_ptr. And you certainly can't construct a second unique_ptr with the pointer you're looking for, because now you're constructing a second owner for the pointer.How about a wrapper for pointers whose only purpose is to provide == with std::unique_ptr? I.e. map.find(compare_ptr(needle)) instead of map.find(needle).Maybe I'm not understanding your suggestion, did you try it? find() takes as a parameter the exact type being stored in the set, so you would have to store your wrapper as the type in the set too.
-scott
I could see that.Would we put that into base/memory/ptr_util.h or base/std_util.h?
--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To post to this group, send email to c...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAHtyhaQN3bjx12cHEu7so5vL39POPMF2A6YgYS8xYnuwtNL6jw%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To post to this group, send email to c...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAAHOzFC69yXGVLA%3DzprrYcQDSkwNjSKF%2BZPKFCZ0zFtGLdZmoQ%40mail.gmail.com.
Sigh.Joe, even though you're probably right, I'm trying to refactor with the smallest chance of breaking everything, and so I'm disinclined to rework a probably-slightly-wrong ownership model in code I don't own.So the proposals here are interesting. I'm looking at killing STLDeleteContainerPairFirstPointers. Nearly all of the uses have net::URLRequest* as the key in a map. Some are easy, where I can put a unique_ptr into an owned object for the value (as in https://codereview.chromium.org/2284863002 and https://codereview.chromium.org/2282053004), which is the parallel of the suggested map<Type*, unique_ptr<Type>> above.What's nasty is ResourcePrefetcher's inflight_requests_ and AutofillDownloadManager's url_fetchers_ where the key is again a net::URLRequest* but the values are tossed around here and there and so I can't easily stick a unique_ptr into them.Would anyone object to the whole find_if deal with them? Yes, we're dropping from logarithmic to linear, but I doubt that it would matter much for the sizes we're dealing with.
Avi--On Tue, Aug 16, 2016 at 6:33 PM, Joe Mason <joenot...@chromium.org> wrote:I don't think P2PSocketDispatcherHost SHOULD be using a set, semantically.The only thing the set is doing, right now, is holding ownership of the DnsRequest's. The raw pointer to the request is also held in the bound OnAddressResolved callback, so the pointer in DnsRequest has to outlive that callback. (In fact I think I see a bug there - are we sure that OnAddressResolved will never be called after OnChannelClosing, which deletes the requests? Even if it's correct, the semantics are extremely unclear. The only way I can see this being safe is if we know that when OnChannelClosing is called, the resolver's actions have already been cancelled so OnAddressResolved will never be called and the resolver will never dereference the raw request pointer.)Since the only thing that actually uses a pointer to that DnsRequest is that callback, and when the callback is called it's safe to delete the DnsRequest immediately (at least it had better be, since that's what it does) I'd say the correct thing to do here is pass the unique_ptr to Bind. Then the callback itself owns the request - when it's called, the request is deleted, and if it never gets called, the request goes away when the callback is discarded. (Which should also take care of the OnChannelClosing case.)Now, it does seem that being able to hold a collection of all the existing DnsRequests might be useful in the future, for example for a function that logs all of them for debugging. So if we decide to keep that container around for future expansion, we would want it to own the memory. In that case, the container has two jobs: one is to hold the ownership of all the DnsRequests, and the other is, given an object of type "parameter-to-OnAddressResolved"(which happens to be a raw pointer to a DnsRequest, but doesn't have to be - we could use the integer request_id instead of the request pointer, for instance) look up the DnsRequest corresponding to that object in the container, and remove it. That second job is naturally the function of a map.This doesn't seem confusing to me. If the container holds raw pointers instead of smart pointers, both the ownership pointer and the parameter-to-OnAddressResolved happen to have the same value, so we can use a set. But I'd argue this is actually a poor use of a set, and conceals the semantics that are actually being used, because it's just a coincidence that they share the type. I find "map<thing we use to reference DnsRequest, owner of DnsRequest>" to be a perfectly appropriate use of map.A map<T*, unique_ptr<T>> IS a bit weird, because we're using T* as an object identifier when it's really a detail of memory use. The problem here is the use of the raw pointer in OnAddressResolved, not the use of a map. We should be finding an actual unique identifier for the object when we use this pattern. So here I'd suggest (if we keep the container at all) changing OnAddressResolved to take the request_id instead of the pointer. (Although that doesn't resolve my doubts about OnChannelClosing.)Another option is to keep storing a set of raw pointers, solely to have a collection of all DnsRequests that exist, and have DnsRequest's destructor remove itself from the set. Then the request would be owned by the bound OnChannelClosing callback, and deleted from the set when that callback fires or is deleted, or when OnChannelClosing is called, whichever comes first.On Mon, Aug 15, 2016 at 5:55 PM, 'Peter Kasting' via cxx <c...@chromium.org> wrote:--On Mon, Aug 15, 2016 at 2:52 PM, Daniel Cheng <dch...@chromium.org> wrote:I guess this is going to be an opinion kind of thing, but I personally map.find() easier to read than find_if(set, <lambda>).I don't strongly disagree; it's the choice of a map when, semantically, a set was desired, that's the more confusing bit. IOW, we pay the cost elsewhere, e.g. at the variable declaration, or when the reader is trying to understand in general the purpose of code that works with this map object.
PK
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To post to this group, send email to c...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAAHOzFC69yXGVLA%3DzprrYcQDSkwNjSKF%2BZPKFCZ0zFtGLdZmoQ%40mail.gmail.com.
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To post to this group, send email to c...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CACWgwAb7buYPja_hai1ROVgxZ%2BAyEgXiUonem05K%2BkvNbapYZA%40mail.gmail.com.
When will we be able to use C++17 features?
On Wed, Aug 31, 2016 at 9:47 AM, Avi Drissman <a...@google.com> wrote:When will we be able to use C++17 features?
Given that Linux can't even use all of C++11 yet
, I'm going to bet 2023.
PK
--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To post to this group, send email to c...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAAHOzFC7%2B%3DBvD53eDvQeE%3D0B%3DL3QyCnEhvAV%3Dz%2BG-G19q0MwpA%40mail.gmail.com.