Почему невозможно создать `std :: filesystem :: path` из итераторов` std :: filesystem :: path`? - PullRequest
0 голосов
/ 12 декабря 2018

Следующий фрагмент кода предназначен для удаления первой части пути, если он существует:

#include <filesystem>

std::filesystem::path strip_prefix(std::filesystem::path p)
{      
  if (auto it{p.begin()}; it != p.end())
  {
    ++it;
    return std::filesystem::path(it, p.end());
  }

  return p;
}

(См .: https://godbolt.org/z/wkXhcw)

Я был удивлен, узнав этоне работает. Код не компилируется, так как конструктор пути принимает только итераторы, которые перебирают последовательности символов. Я могу видеть использование этого, но зачем ограничивать конструкцию только такими типами итераторов? На мой взгляд, это противоречит интуитивноподдерживать построение пути из своих собственных итераторов. Насколько я знаю, большинство других типов STL поддерживают эту идиому.

Какая эффективная реализация для достижения той же цели, кроме полной реконструкции нового пути?

Обновление : в этом контексте я нашел следующее обсуждение уместным / забавным: http://boost.2283326.n4.nabble.com/boost-filesystem-path-frustration-td4641734.html. Я согласен с Дейвом здесь. Я думаю, что видеть путь как контейнер элементов путиочень естественный способ взглянуть на это (с точки зрения программиста).

1 Ответ

0 голосов
/ 12 декабря 2018

Самое простое решение для объединения сегментов для создания нового path - это просто std::accumulate().

Для вашего конкретного случая использования я бы сделал что-то вроде этого:

std::filesystem::path strip_prefix(std::filesystem::path p)
{
    if(p.empty()) return p;
    return std::accumulate(std::next(p.begin()), p.end(), 
                           std::filesystem::path{}, std::divides{});
}

А почему нет конструктора (или, может быть, свободной функции) для этого?Я не знаю.Это похоже на необходимость, возникающую при работе с путями, но комитет, как правило, неохотно добавляет удобные функции к стандартным классам, если тот же результат может быть достигнут с помощью вызова стандартного алгоритма.

...