C++ Logo

STD-PROPOSALS

Advanced search

Subject: Re: [std-proposals] A Generic Library for Lifetime Extension and In-place Construction
From: Mingxin Wang (mingxwa_at_[hidden])
Date: 2019-05-04 22:22:49



From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Sent: Saturday, May 4, 2019 11:30 PM
To: std-proposals_at_[hidden]
Cc: Mingxin Wang <mingxwa_at_[hidden]>
Subject: Re: [std-proposals] A Generic Library for Lifetime Extension and In-place Construction

You seem to mention lifetime extension only in Section 3.1, and you don't give any examples.
(You also mention lifetime extension of references, as if that's a thing. References don't have any lifetime/ownership semantics — they are "trivially destructible," so to speak — and so it doesn't make sense to talk about their lifetimes. Only objects have lifetimes.)
Please either
(A) update the paper with some examples of code that benefits from lifetime extension and explain what your proposal has to do with lifetime extension;
(B) decide that what you're talking about is not C++ "lifetime extension<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F17362673%2Ftemporary-lifetime-extension&data=01%7C01%7Cmingxwa%40microsoft.com%7Cdd49980d8f2e41a92edb08d6d0a5706d%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=Sq0hxPNe6Rir4l40KRLt23UOKMXDqD%2BivwYf%2FrewWqM%3D&reserved=0>" but rather some other idiosyncratic notion, and pick a new phrase to refer to it; or
(C) eliminate all mentions of "lifetime extension" within the paper.

If my understanding is correct, the standard only defined “lifetime extension” for temporaries within an expression, while the proposal defined that for arguments across expressions. But anyway, I think it is necessary to clarify the difference at the beginning of the proposal, thanks.

There are many examples for extending the lifetime of an argument in the standard library as illustrated in Section 2, including `std::tuple`, `std::make_tuple`, `std::async`, the constructor of `std::thread`/`std::optional`, etc. I think all of them has the potential to be optimized.

As for references, we do not need to worry about the lifetime issue if we are not talking about template library. However, in some cases users need to pass references to a template library, and library designers usually want to have a unified way to process values and references. For example, as is illustrated in Section 3.1.2, the constructor of `std::thread` or function template `std::make_pair`, `std::make_tuple` generally accept `std::reference_wrapper` for reference arguments.

In Section 1, your example is
std::tuple<X, int>{ X{1, 0.37}, 123 };
Can you explain again why the existing library facilities don't meet your needs?

Because:

  1. I want to avoid potential and unnecessary runtime overhead during decay copy or type conversion (the same as other facilities in the standard that support in-place construction), and
  2. I think it would be easier to use and potentially have higher performance if a template library (not only for `std::tuple` and other facilities in the standard, but also for 3rd party template libraries) directly support non-move-constructible types if necessary (e.g., storing a concurrent context that contains mutexes or atomics as illustrated in Section 2). After all, it is technically feasible to support non-move-constructible types, as long as there is a well-designed API for constructor or function template.

If I really wanted to avoid X's move-constructor for some reason, I would write that as
    std::tuple<X, int>(std::piecewise_construct, std::make_tuple(1, 0.37), std::make_tuple(123));

...Ooh. Piecewise_construct does not exist for std::tuple, only for std::pair. That's very surprising!
https://stackoverflow.com/questions/11846634/why-is-there-no-piecewise-tuple-constructionxwa%40microsoft.com%7Cdd49980d8f2e41a92edb08d6d0a5706d%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=VUzszLq3it%2BR9ZPJWCNSl3mBy4Mrp1W%2B4QmH6Cs%2B6Lg%3D&reserved=0>

Okay, so can you

  1. explain why your paper takes the approach it does, instead of just adding a piecewise_construct constructor for std::tuple, or

Because this proposal is intended to provide a more generic solution for all template libraries that require lifetime extension for arguments.

(B) change it to propose a piecewise_construct constructor for std::tuple instead?

Because:

  1. `std::tuple` is a motivating example for this proposal, and there are many other facilities in the standard having this issue (as illustrated in Section 2). I think it would be bloated to put them in a single proposal, and that is also not conducive for discussion.
  2. Updating an existing API requires a lot more work, and there shall be more considerations in compatibility. As the last sentence in Section 2 says: “since there should be more considerations in compatibility, this proposal only aims to provide a reusable solution rather than updating existing APIs in the standard”.



STD-PROPOSALS list run by herb.sutter at gmail.com

Standard Proposals Archives on Google Groups