cplusplus / draft

C++ standards drafts
http://www.open-std.org/jtc1/sc22/wg21/
5.66k stars 748 forks source link

[std] Where template can be replaced with auto, or vice versa #4822

Open JohelEGP opened 3 years ago

JohelEGP commented 3 years ago

Following the discussion at #4817, I searched the WD for &&... and found some places where these could be swapped.

jwakely commented 3 years ago

Following the discussion at #4817, I searched the WD for &&... and found some places where these could be swapped.

* Use familiar template syntax for lambdas: [allocator.uses.construction], [allocator.adaptor.members].

[&alloc]<class... Args1>(Args1&&... args1) would allow us to avoid decltype(args1) but I'm not sure it's significantly better, or worth changing.

* Remove redundant parameter pack:

  * [dcl.fct.def.coroutine]'s example.
  * [unique.ptr.creation]'s `=delete`d overloads. Perhaps useful for symmetry with the non-deleted overloads.

Keeping them symmetrical with the other overloads seems more useful than whatever benefit might come from using auto. We still need a template-head anyway for the non-deduced T template parameter.

  * In containers: [deque.modifiers], [list.modifiers], [vector.modifiers], [vector.bool], [map.overview]'s `emplace`{,`_hint`}, [multimap.overview], [set.overview], [multiset.overview], [unord.map.overview]'s `emplace`{,`_hint`}, [unord.multimap.overview], [unord.set.overview], [unord.multiset.overview].

Those names are used in the function bodies in actual implementations. I am not persuaded that changing them has any benefit.

jwakely commented 3 years ago

Thanks for the survey though!

jwakely commented 3 years ago

I think if we want a policy, then "a sink or catch-all where you don't care about the names or types of the parameters" seems like a good place to use auto&& or auto&&...

For other cases, I don't have a good suggestion (or preference). The survey here shows there aren't too many examples where it matters.

Maybe "if it's plausible that the specification, or just an implementation, would want to name the types, then use a < template-parameter-list > to give them names" makes sense, although it's a bit vague. I'd like to avoid changing things like list::emplace to use auto&&, only to have to change it back at a later date because we want to state a precondition or constraint in terms of the type. That guideline would suggest we should change [allocator.uses.construction] and [allocator.adaptor.members] to name the types, and maybe change the deleted make_unique overloads to:

template<class T> unspecified make_unique(auto&&...) = delete;

Now that I look at the line above, I think I do like it for make_unique. Only T matters here (for the Constraints: element) and the other arguments are "a catch-all where you don't care about the names or types of the parameters".

JohelEGP commented 3 years ago

That does seem like an improved make_unique.

I'd refine the first suggestion for a policy to

-a sink or catch-all where you don't care about the names or types of the parameters
+a sink or catch-all where the names and types of the parameters don't matter

I think that's less subjective and might include (perhaps not clearly enough) the case where it does matter for an implementation.

As usual, I agree with your points.

jwakely commented 3 years ago

That's much better phrasing, and I think it does nicely cover the "might need to refer to them in the spec or an impl" case as well as the "sink with unused/ignored arguments" case.

tkoeppe commented 1 year ago

Editorial meeting consensus: The proposed policy https://github.com/cplusplus/draft/issues/4822#issuecomment-901139571 sounds good, and we should adopt it. Only very few parts of the standard are affected.

We welcome pull requests to change make_unique accordingly.

We can also make the reverse change in individual cases where there is a clear benefit, without having a wider policy.