Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.std.c++ > #500

Re: make_shared and friends.

From Jason McKesson <jmckesson@gmail.com>
Newsgroups comp.std.c++
Subject Re: make_shared and friends.
Date 2012-05-01 11:29 -0700
Organization http://groups.google.com
Message-ID <14621972.860.1335819954688.JavaMail.geo-discussion-forums@ynce8> (permalink)
References <5583145.28.1335476739188.JavaMail.geo-discussion-forums@ynnn35> <jnep30$d2s$1@dont-email.me> <17423064.271.1335555821298.JavaMail.geo-discussion-forums@vbq5> <jnj0aq$b2b$1@dont-email.me>

Show all headers | View raw


On Sunday, April 29, 2012 11:59:51 PM UTC-7, Daniel Krügler wrote:
> Am 29.04.2012 02:02, schrieb Jason McKesson:
> [..]
> >
> > It's not so much a problem as wondering how this is supposed to work.
> > Without the ability to have `make_shared` be a friend (in a useful
> > way), it is impossible to *force* users to use `make_shared`.
>
>
> I don't understand your question: Surely it cannot be the
> responsibility of a library implementation to enforce user code to use
> some particular component.

A good API makes it difficult if not impossible to do things
incorrectly. And if a particular object has `enable_shared_from_this`
as a base class, then it is incorrect to create an instance of that
object *without* a shared_ptr.

So you have to either force the user to use `make_shared` or force the
user to use factory functions. Enforcing either requires the use of
private constructors.

> > You also can't effectively combine factory functions with
> > `make_shared`. So you lose a lot of the benefits of them when dealing
> > with factories.
>
>
> I don't understand what you are trying to say here.

See above. You usually enforce the use of factory functions by making
constructors private.

> > It shouldn't be too much of a burden on implementations to force them
> > to do the final construction of the type within `make_shared` itself,
> > rather than in some object they create.
>
>
> Even if some particular implementations decides to do so, this won't be
> portable code anymore. Standardizing this for this special function
> template would also seem very odd, a more general policy should be
> considered, if needed.

Extending it to `emplace` member functions wouldn't be a bad idea.

> In regard to the "burden" I think you are
> mislead. The guarantee that the actual code is called in a particular
> location is *not* sufficient. Todays high-quality implementations of
> the Standard Library usually provide a lot of static concept-checking
> to ensure that user-types satisfy the requirements of the standard.
> One requirement is that
>
> "The expression ::new (pv) T(std::forward<Args>(args)...), where pv
> has type void* and points to storage suitable to hold an object of
> type T, shall be well formed."
>
> If a static concept-checking tool attempts to validate this it won't
> help that you have assigned friendship to the function: The
> static-tool machinery would also require this friendship.

The wording would have to be changed. That expression would be valid,
but *only* within the make_shared function itself. So any concept
checking (if it's still possible) would have to be done within the
function, not in extra classes and so forth.

> Don't feel attempted to hope that assigning friendship to types or
> functions other than those under your control is a feasible approach.
> In fact, you really should *know* the one, to whom you become friend
> with ;-)
>
> > Also, allocate_shared won't help, because that's about the allocation
> > of the block of memory, not the calling of the constructor.
>
>
> Yes, the current wording is defective in this regard, but the proposed
> resolution of
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2070
>
> would ensure that the allocator's construct and destroy function will
> be used. gcc 4.8 has already implemented the P/R for evaluation
> purposes.

True, but that requires a *lot* of boilerplate to do something that
ought to be very, very simple. You have to make a special allocator to
be used for instances of the class, and most of its methods will just
call the std::allocator function. It requires the user to use the
less-well-known `allocate_shared` instead of `make_shared`. It's less
idiomatic.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]

Back to comp.std.c++ | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

make_shared and friends. Jason McKesson <jmckesson@gmail.com> - 2012-04-27 11:12 -0700
  Re: make_shared and friends. Daniel Krügler<daniel.kruegler@googlemail.com> - 2012-04-27 11:47 -0700
    Re: make_shared and friends. Jason McKesson <jmckesson@gmail.com> - 2012-04-28 17:02 -0700
      Re: make_shared and friends. Daniel Krügler <daniel.kruegler@googlemail.com> - 2012-04-29 23:59 -0700
        Re: make_shared and friends. Jason McKesson <jmckesson@gmail.com> - 2012-05-01 11:29 -0700
          Re: make_shared and friends. "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2012-05-02 11:11 -0700
          Re: make_shared and friends. Daniel Krügler <daniel.kruegler@googlemail.com> - 2012-05-02 11:12 -0700
  Re: make_shared and friends. "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2012-04-28 17:00 -0700

csiph-web