Являются ли экспериментальные возможности современного С++ надежными для долгосрочных проектов?
У меня есть проект, который в настоящее время использует С++ 11/14, но для него требуется нечто вроде std::filesystem
, которое доступно только на С++ 17, и поэтому у меня нет возможности его использовать. Я вижу, однако, что он доступен в моем текущем компиляторе как std::experimental::filesystem
. Является ли хорошей идеей использовать экспериментальные функции, предполагая, что в будущем я мог бы добавить что-то вроде:
#ifdef CXX17 //if this is C++17
std::filesystem::something ...;
#else
std::experimental::filesystem::something ...;
#endif
Мои проблемы:
1. Гарантировано ли, что все совместимые компиляторы имеют одни и те же экспериментальные возможности?
2. Являются ли экспериментальные особенности склонными к большим изменениям, которые делают их ненадежными?
Может быть, есть еще кое-что, о чем можно подумать. Почему я должен или не должен использовать их? Я озадачен новым проектом и не знаю, что решать.
Ответы
Ответ 1
- Гарантировано ли, что все совместимые компиляторы имеют одни и те же экспериментальные возможности?
Нет, экспериментальные функции необязательны.
- Являются ли экспериментальные признаки склонными к большим изменениям, которые делают их ненадежными?
Да, комитет С++ может даже решить отказаться от функции или в процессе стандартизации, может возникнуть дефект, который заставил бы функцию изменить.
Как правило, не следует полагаться на экспериментальные возможности. Экспериментальные особенности - это именно то, что говорит слово (т.е. Экспериментировать).
Ответ 2
Кто-то из аудитории задал вопрос во время "С++ Standard Library Panel" на CppCon 2016 (std::experimental] будет абсолютно [...] пуленепробиваемой. [...] Что-то вроде [...] заголовка <random>
в TR1, [это было] действительно, очень приятно в TR1, и вы могли иметь абсолютно пуленепробиваемую реализацию этого, но оказалось, что интерфейс существенно изменился [до выпуска] С++ 11 и [...], если бы мы знали, что мы делаем сейчас, добавив experimental
, было бы лучшим сигналом для людей, которые: "Эй, может быть, вы не хотите использовать std::experimental::variate_generator
, потому что ha-ha он исчезнет в С++ 11".
Похоже, что среди разработчиков стандартной библиотеки и членов комитета есть желание, что в будущем, по крайней мере, содержание пространства имен std::experimental
должно быть по-настоящему "экспериментальным" по своему характеру, и его не следует принимать что что-то в std::experimental
превратит его в стандарт С++.
И нет, насколько я понимаю, до стандартных поставщиков библиотек зависит, предоставляют ли они реализации для различных функций в std::experimental
.
Ответ 3
"Экспериментальный" - слегка преувеличенный термин. Библиотека filesystem
возникла в Boost и прошла через несколько итераций, прежде чем отправляться в ISO.
Однако стандарты ИСО преднамеренно очень консервативны. Называя это экспериментальным, ISO явно не обещает, что именование будет стабильным; это совершенно ясно, что вам нужно будет повторно обратиться к вашему коду некоторое время в будущем. Но, зная ИСО, вероятно, что будет руководство.
Что касается совместимости между компиляторами, ожидайте, что это будет разумно. Но будут угловые случаи (например, относительные пути для Windows), и именно поэтому будущий стандарт может нарушить существующий код. В идеале, это сломает вам код тогда и только тогда, когда вы зависете от этого углового случая, но это не гарантия.
Ответ 4
Может быть, есть еще кое-что, о чем можно подумать.
Несколько соображений:
-
Как мультиплатформенный проект? Если задействован только один компилятор, вы можете проверить его реализацию и послужной список. Или спросите их!
-
Насколько велика ваша кодовая база? Насколько значительным будет влияние изменений?
-
Насколько фундаментальными для вашего проекта являются функции, предоставляемые API/библиотекой/функцией?
-
Каковы альтернативы?
- Используйте экспериментальную функцию, затем адаптируйте код к изменениям, когда/если он станет стандартизованным. Может быть так же просто, как удалить
experimental::
или так же сильно, как принудительные обходные пути.
- Добавить слой абстракции (комментарий Сергея Балеста). Если экспериментальная функция изменится, ваши повторные записи будут изолированы. Для стандартной функции это может быть излишним (std:: filesystem уже является уровнем абстракции...).
- Используйте другой API/библиотеку. Те же вопросы: зрелость? Надежность? стабильность? портативность? простота использования? особенности?
- В случае std:: filesystem (или сетевой TS) в качестве альтернативы или резервного копирования существует boost:: filesystem (соответственно boost:: asio), в случае, если
experimental
не работает или исчезает.