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

### 3244. Constraints for `Source` in §[fs.path.req] insufficiently constrainty

Section: 29.12.6.4 [fs.path.req] Status: C++20 Submitter: Casey Carter Opened: 2019-08-02 Last modified: 2021-02-25

Priority: 0

View all issues with C++20 status.

Discussion:

`std::filesystem::path` has a number of functions - notably including a conversion constructor template (29.12.6.5.1 [fs.path.construct]) and assignment operator template (29.12.6.5.2 [fs.path.assign]) - that accept `const Source&`. Per 29.12.6.4 [fs.path.req] paragraph 2:

> -2- Functions taking template parameters named `Source` shall not participate in overload resolution unless either

> (2.1) — `Source` is a specialization of `basic_string` or `basic_string_view`, or

> (2.2) — the qualified-id `iterator_traits<decay_t<Source>>::value_type` is valid and denotes a possibly `const` encoded character type.

`iterator_traits<decay_t<path>>::value_type` is not valid in C++17, so this specification was sufficient to guard against the conversion constructor template (respectively assignment operator template) "pretending" to be copy constructor (respectively copy assignment operator). P0896R4 "The One Ranges Proposal", however, altered the definition of `iterator_traits` in the working draft. It now has some convenient default behaviors for types that meet (roughly) the syntax of the `Cpp17InputIterator` requirements. Notably those requirements include copy construction and copy assignment.

In the working draft, to determine the copyability of `std::filesystem::path` we must perform overload resolution to determine if we can initialize a `path` from a constant lvalue of type `path`. The conversion constructor template that accepts `const Source&` is a candidate, since its second argument is defaulted, so we must perform template argument deduction to see if this constructor is viable. `Source` is deduced to `path` and we then must check the constraint from 29.12.6.4 [fs.path.req] paragraph 2.2 (above). Checking the constraint requires us to specialize `iterator_traits<path>`, which (per 23.3.2.3 [iterator.traits] paragraph 3.2) requires us to determine if `path` satisfies the exposition-only `cpp17-input-iterator` concept, which requires `path` to be copyable.

We've completed a cycle: determining if `path` is copyable requires us to first determine if `path` is copyable. This unfortunate constraint recursion can be broken by explicitly specifying that `path` is not a valid `Source`.

[2019-08-17 Issue Prioritization]

Status to Tentatively Ready and priority to 0 after seven positive votes on the reflector.

Proposed resolution:

This wording is relative to N4830.

1. Modify 29.12.6.4 [fs.path.req] as indicated:

   > -2- Functions taking template parameters named `Source` shall not participate in overload resolution unless `Source` denotes a type other than `path`, and either

   > […]