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

3754. Class template expected synopsis contains declarations that do not match the detailed description

Section: 22.8.6.1 [expected.object.general] Status: WP Submitter: S. B. Tam Opened: 2022-08-23 Last modified: 2022-11-17

Priority: Not Prioritized

View all other issues in [expected.object.general].

View all issues with WP status.

Discussion:

22.8.6.1 [expected.object.general] declares the following constructors:

template<class G>
  constexpr expected(const unexpected<G>&);
template<class G>
  constexpr expected(unexpected<G>&&);

But in [expected.object.ctor], these constructors are declared as:

template<class G>
  constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e);
template<class G>
  constexpr explicit(!is_convertible_v<G, E>) expected(unexpected<G>&& e);

Note that they have no explicit-specifiers in 22.8.6.1 [expected.object.general], but are conditionally explicit in [expected.object.ctor].

I presume that 22.8.6.1 [expected.object.general] is missing a few explicit(see below).

The same inconsistency exists in 22.8.7 [expected.void].

[2022-09-05; Jonathan Wakely provides wording]

In N4910 the expected synopses had explicit(see below) on the copy and move constructors. That was fixed editorially, but this other inconsistency was not noticed.

[2022-09-07; Moved to "Ready" at LWG telecon]

[2022-11-12 Approved at November 2022 meeting in Kona. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4917.

  1. Change 22.8.6.1 [expected.object.general] as indicated:

    // 22.8.6.2, constructors
    constexpr expected();
    constexpr expected(const expected&);
    constexpr expected(expected&&) noexcept(see below);
    template<class U, class G>
      constexpr explicit(see below) expected(const expected<U, G>&);
    template<class U, class G>
      constexpr explicit(see below) expected(expected<U, G>&&);
    
    template<class U = T>
      constexpr explicit(see below) expected(U&& v);
    
    template<class G>
      constexpr explicit(see below) expected(const unexpected<G>&);
    template<class G>
      constexpr explicit(see below) expected(unexpected<G>&&);
    
    template<class... Args>
      constexpr explicit expected(in_place_t, Args&&...);
    
  2. Change 22.8.7.1 [expected.void.general] as indicated:

    // 22.8.7.2, constructors
    constexpr expected() noexcept;
    constexpr expected(const expected&);
    constexpr expected(expected&&) noexcept(see below);
    template<class U, class G>
      constexpr explicit(see below) expected(const expected<U, G>&&);
    
    template<class G>
      constexpr explicit(see below) expected(const unexpected<G>&);
    template<class G>
      constexpr explicit(see below) expected(unexpected<G>&&);
    
    constexpr explicit expected(in_place_t) noexcept;