Являются ли экспериментальные возможности современного С++ надежными для долгосрочных проектов?

У меня есть проект, который в настоящее время использует С++ 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

  • Гарантировано ли, что все совместимые компиляторы имеют одни и те же экспериментальные возможности?

Нет, экспериментальные функции необязательны.

  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 не работает или исчезает.