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

### 2711. `path` is convertible from approximately everything under the sun

Section: 29.12.6.5.1 [fs.path.construct] Status: C++17 Submitter: Tim Song Opened: 2016-05-10 Last modified: 2017-07-30

Priority: 1

View all issues with C++17 status.

Discussion:

The unconstrained `template<class Source> path(const Source& source);` constructor defines an implicit conversion from pretty much everything to `path`. This can lead to surprising ambiguities in overload resolution.

For example, given LWG 2676's proposed resolution, the following code appears to be ambiguous:

>     struct meow {
>       operator const char *() const;
>     };

>     std::ifstream purr(meow{});

because a `meow` can be converted to either a `path` or a `const char*` by a user-defined conversion, even though part of the stated goal of LWG 2676's P/R is to avoid "break[ing] user code depending on user-defined automatic conversions to the existing argument types".

Previous resolution [SUPERSEDED]:

> This wording is relative to N4582.

> > [Drafting note: `decay_t<Source>` handles both the input iterator case (29.12.6.4 [fs.path.req]/1.2) and the array case (29.12.6.4 [fs.path.req]/1.3). The level of constraints required is debatable; the following wording limits the constraint to "is a `basic_string` or an iterator", but perhaps stronger constraints (e.g., an `iterator_category` check in the second case, and/or a `value_type` check for both cases) would be desirable.]

> 1. Change 29.12.6.5.1 [fs.path.construct] as indicated:

>    >     template <class Source>
>    >       path(const Source& source);
>    >     template <class InputIterator>
>    >       path(InputIterator first, InputIterator last);

>    > > -4- Effects: Constructs an object of class `path`, storing the effective range of `source` (27.10.8.3) or the range `[first, last)` in `pathname`, converting format and encoding if required (27.10.8.2.1).

>    > > -?- Remarks: The first overload shall not participate in overload resolution unless either `Source` is a specialization of `basic_string` or the qualified-id `iterator_traits<decay_t<Source>>::value_type` is valid and denotes a type (13.10.3 [temp.deduct]).

[2016-05-28, Eric Fiselier comments suggests alternative wording]

Functions taking `EcharT` or `Source` parameter types often provide additional overloads with the same arity and concrete types. In order to allow conversions to these concrete types in the interface we need to explicitly disable the `EcharT` and `Source` overloads.

[2016-06-19, Eric and Tim improve the wording]

[2016-06, Oulu]

Voted to Ready 8-0 Monday morning in Oulu

Proposed resolution:

This wording is relative to N4594.

> [Drafting note: Functions taking `EcharT` or `Source` parameter types often provide additional overloads with the same arity and concrete types. In order to allow conversions to these concrete types in the interface we need to explicitly disable the `EcharT` and `Source` overloads.]

1. Change 29.12.3 [fs.req] as indicated:

   > -2- Template parameters named `EcharT` shall be Functions with template parameters named `EcharT` shall not participate in overload resolution unless `EcharT` is one of the encoded character types.

2. Insert a new paragraph between 29.12.6.4 [fs.path.req] p1 and p2 as indicated:

   > -?- Functions taking template parameters named `Source` shall not participate in overload resolution unless either `Source` is a specialization of `basic_string` or the qualified-id `iterator_traits<decay_t<Source>>::value_type` is valid and denotes a possibly `const` encoded character type (13.10.3 [temp.deduct]).