Skip to content

Instantly share code, notes, and snippets.

@sylveon
Last active May 28, 2019 20:35
Show Gist options
  • Save sylveon/c5824d8bcf98a48e0027dc8ec7e9233a to your computer and use it in GitHub Desktop.
Save sylveon/c5824d8bcf98a48e0027dc8ec7e9233a to your computer and use it in GitHub Desktop.
Improving interoperability between std::filesystem::path and std::string_view

Improving interoperability between std::filesystem::path and std::string_view

Document number: D0000R0
Date: 2019-05-28
Project: WG21, Library Working Group
Author: Charles Milette charles.milette@gmail.com

1. Introduction

This proposal allows assigning a type convertible to a std::string_view to a std::filesystem::path.

Note: text in this proposal assumes that std::string_view matches std::filesystem::path::value_type to avoid retyping std::basic_string_view<std::filesystem::path::value_type> frequently.

2. Motivation

One of the many uses of std::string_view and its different encoding friends is to provide a common interface to the countless string types provided by the many frameworks or libraries out there. This way, one can write their string manipulation functions so that it can be called with either a std::string, winrt::hstring (a string type in Microsoft’s C++/WinRT library) or another std::string_view without writing templates (solution which doesn’t works easily when said string types have a different interface), or duplicating code (violating DRY).

Thanks to implicit conversion taking place, this establishes a two-way "I don't care" relationship, where the caller does not needs to care about the callee using std::string_view, and the callee does not needs to care about the caller using a third-party string type. This relationship is what gives std::string_view its power to allow easily writing universal, elegant, fast and non-copying APIs when pertaining to strings.

Currently, [fs.path.req] is worded so that only std::basic_string_view<EcharT, traits> itself is accepted, and not types convertible to it, which makes assigning a std::filesystem::path from those types either an error or a not so nice line. It breaks that two-way relationship, because the caller needs to care about std::filesystem::path needing std::string_view due to implicitly convertible types not being allowed.

#include <filesystem>
#include <string_view>

// Provided for demonstration purposes, a real custom string type would be more complete.
struct custom_string
{
    operator std::string_view() const
    {
        return "/home/JohnDoe/Documents";
    }
};

int main()
{
    std::filesystem::path path;
    custom_string str;
    std::string_view view = str;

    path = view; // ok
    path = str; // error
    path = static_cast<std::string_view>(str); // ok
}

Another point for this is that std::filesystem::path can be considered as a special version of std::string destined for file paths (as shown by members like operator string_type that allows better interoperability with older code). If the variable path in the previous example where to be a std::string, the line where an error occurs would be well-formed. As such, to keep consistency between the two standard library types, the operation should be allowed on std::filesystem::path.

3. Impact on the Standard

This proposal only affects one standard library class and header.

I do not believe that the suggested change would cause any breakage, because all existing valid inputs will still be accepted, this proposal only adds more possible inputs:

  • std::basic_string will be handled by its convertibility to std::basic_string_view;
  • Passing a std::basic_string_view directly will still work;
  • Pointers to null-terminated strings or arrays are also still accepted, because they can either convert to std::basic_string_view or are valid input iterators;
  • Finally, input iterators are unchanged.

4. Proposed Changes

???

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment