This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

3451. Inconsistently explicit deduction guides

Section: 23.4.3 [basic.string], 26.7.14.2 [range.join.view] Status: New Submitter: Johel Ernesto Guerrero Peña Opened: 2020-06-11 Last modified: 2020-07-17

Priority: 3

View other active issues in [basic.string].

View all other issues in [basic.string].

View all issues with New status.

Discussion:

The library inconsistently marks deduction guides as explicit. join_view and basic_string account for the only two occurrences of unconditionally explicit deduction guides. All other deduction guides have no explicit-specifier. Following is a list of unconditionally explicit constructors with their deduction guides.

template<class Y>
  explicit shared_ptr(const weak_ptr<Y>& r);

template<class T>
  shared_ptr(weak_ptr<T>) -> shared_ptr<T>;

template<class T>
  constexpr explicit basic_string(const T& t, const Allocator& a = Allocator());

template<class charT,
         class traits,
         class Allocator = allocator<charT>>
  explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
    -> basic_string<charT, traits, Allocator>;

explicit queue(const Container&);
explicit queue(Container&&);

template<class Container>
  queue(Container) -> queue<typename Container::value_type, Container>;

explicit stack(const Container&);
explicit stack(Container&&);

template<class Container>
  stack(Container) -> stack<typename Container::value_type, Container>;

constexpr explicit join_view(V base);

template<class R>
  explicit join_view(R&&) -> join_view<views::all_t<R>>;

constexpr explicit common_view(V r);

template<class R>
  common_view(R&&) -> common_view<views::all_t<R>>;

constexpr explicit reverse_view(V r);

template<class R>
  reverse_view(R&&) -> reverse_view<views::all_t<R>>;


explicit zoned_time(TimeZonePtr z);
explicit zoned_time(string_view name);

template<class TimeZonePtrOrName>
  zoned_time(TimeZonePtrOrName&&)
    -> zoned_time<seconds, time-zone-representation<TimeZonePtrOrName>>;

template<class C>
explicit stop_callback(const stop_token& st, C&& cb)
    noexcept(is_nothrow_constructible_v<Callback, C>);
template<class C>
explicit stop_callback(stop_token&& st, C&& cb)
    noexcept(is_nothrow_constructible_v<Callback, C>);

template<class Callback>
  stop_callback(stop_token, Callback) -> stop_callback<Callback>;

[2020-07-17; Priority set to 3 in telecon]

Proposed resolution:

This wording is relative to N4861.

  1. Modify 23.4.3 [basic.string], class template basic_string synopsis, as indicated:

    […]
    template<class charT,
             class traits,
             class Allocator = allocator<charT>>
      explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
        -> basic_string<charT, traits, Allocator>;
    […]
    
  2. Modify 23.4.3.3 [string.cons] as indicated:

    […]
    template<class charT,
             class traits,
             class Allocator = allocator<charT>>
      explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
        -> basic_string<charT, traits, Allocator>;
    […]
    

    -22- Constraints: Allocator is a type that qualifies as an allocator (24.2.2 [container.requirements.general]).

  3. Modify 26.7.14.2 [range.join.view], class template join_view synopsis, as indicated:

    […]
    template<class R>
      explicit join_view(R&&) -> join_view<views::all_t<R>>;
    […]