2970. Return type of std::visit misspecified

Section: 22.6.7 [variant.visit] Status: C++20 Submitter: Tim Song Opened: 2017-05-31 Last modified: 2021-02-25

Priority: 2

View all other issues in [variant.visit].

View all issues with C++20 status.

Discussion:

[variant.visit]/1 correctly uses "type and value category", but then p3 describes the return type of visit to be "the common type of all possible INVOKE expressions of the Effects: element." The type of an expression is never a reference type, due to [expr]/5 removing the referenceness "prior to any further analysis", so this wording as written says that visit always returns a non-reference type, which is presumably not the intent.

[2017-07 Toronto Monday issue prioritization]

Priority 2; Matt to provide wording

[2018-01-11, Thomas Köppe comments and suggests wording]

The return type of std::visit (originating by P0088R3 accepted during the Oulo 2016 meeting) is currently misspecified and refers only to the common type of all the possible visitation calls, without attention to the value category. This seems unintended, and we should preserve the value category.

[2017-01-24, Daniel comments]

This issue should be reviewed in common with LWG 3052.

[ 2018-02-23 Moved to Tentatively Ready after 6 positive votes on c++std-lib. ]

[2018-06 Rapperswil: Adopted]

Proposed resolution:

This wording is relative to N4727.

  1. Modify 22.6.7 [variant.visit] as indicated:

    template<class Visitor, class... Variants>
      constexpr see below visit(Visitor&& vis, Variants&&... vars);
    

    […]

    -3- Returns: e(m), where m is the pack for which mi is varsi.index() for all 0 <= i < n. The return type is the type of e(m)decltype(e(m)).

    […]