Как сделать так, чтобы std :: filesystem соответствовала стандартам Visual Studio 2015?

У меня есть проект, который в настоящее время заблокирован в Visual Studio 2015. Однако я хочу написать код, максимально соответствующий стандартам.

Я хочу использовать std::filesystem но это не вошло в стандарт до C ++ — 17. К счастью, почти все доступно, только в std::experimental::filesystem::v1 Пространство имен. Я не фанат одеял using директивы; Я предпочитаю полностью охватывать вещи, чтобы было ясно, откуда они берутся. Так что я не собираюсь просто положить в глобальный using заявление. Требуется какое-то волшебство, чтобы убедить компилятор сделать то, что я хочу.

Это была моя первая попытка:

#include <filesystem>
#if defined(_MSC_VER) && _MSC_VER <= 1900 // VS 2015
namespace std {
namespace filesystem {
using path = std::experimental::filesystem::v1::path;
}
}
#endif

Это работает довольно хорошо, и std::filesystem::path теперь доступно. Я тестировал создание и использование path объекты и это работает.

По мере продвижения вперед я знаю, что мне понадобится больше вещей. Я задавался вопросом, может ли быть способ просто внести все это:

namespace std {
namespace filesystem {
using std::experimental::filesystem::v1;
}
}

Это казалось шагом назад. Ничто не кажется видимым. Оглядываясь назад, я думаю, что это имеет смысл, поскольку сфера действия using Оператор заканчивается закрывающей скобкой на следующей строке.

Далее я хочу получить directory_entry, Кажется, работает та же техника

namespace std {
namespace filesystem {
using directory_entry = std::experimental::filesystem::v1::directory_entry;
}
}

Опять же, компилятор выглядит счастливым.

Теперь я хочу использовать std::directory::create_directories, Однако это функция, а не класс, поэтому тот же метод не сработает.

я думал так std::function может быть специально для этого, но мне не повезло. Я старался

namespace std {
namespace filesystem {
function<bool(path)> create_directories = std::experimental::filesystem::v1::create_directories;
}
}

и компилятор говорит

Error   C2440   'initializing': cannot convert from 'overloaded-function' to 'std::function<bool (std::filesystem::path)>'

Есть две перегрузки функции (одна принимает второй аргумент, чтобы вернуть код ошибки, а не выдавать исключение).

Я застрял. Это должно быть возможно, но мой C ++ — foo слабый.

5

Решение

Ответ лежит в сообщении об ошибке, и помощь, необходимая для создания экземпляра std::function для перегруженного метода. Благодаря MFisherKDX за то, что указал мне Вот и к W.F. для ответа, что работает.

Игнорируя вопрос о том, является ли законным, моральным или хорошим вкусом расширение стандартного пространства имен (потому что в этом случае я считаю, что это как минимум 2 из 3), вот мой полностью прокомментированный обходной путь:

#if defined(_MSC_VER) && _MSC_VER <= 1900
// Visual Studio 2015 work-around ...
// std::filesystem was incorporated into C++-17 (which is obviously after VS
// 2015 was released). However, Microsoft implemented the draft standard in
// the std::exerimental namespace. To avoid nasty ripple effects when the
// compiler is updated, make it look like the standard here
#include <functional>
namespace std {
namespace filesystem {
using directory_entry = std::experimental::filesystem::v1::directory_entry;
using directory_iterator = std::experimental::filesystem::v1::directory_iterator;
function<bool(path const&)> create_directories =
static_cast<bool(*)(path const&)>(
std::experimental::filesystem::v1::create_directories);
}
}
#endif

ОБНОВИТЬ: Себастьян было самое простое решение.

#if defined(_MSC_VER) && _MSC_VER <= 1900
// Visual Studio 2015 work-around ...
// std::filesystem was incorporated into C++-17 (which is obviously after VS
// 2015 was released). However, Microsoft implemented the draft standard in
// the std::exerimental namespace. To avoid nasty ripple effects when the
// compiler is updated, make it look like the standard here
namespace std {
namespace filesystem = experimental::filesystem::v1;
}
#endif

Кстати, для gcc 7.3 требуется почти такой же обходной путь, кроме случаев, когда вы не можете

#include <filesystem>

но должен

#include <experimental/filesystem>

вместо

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]