Я долгое время работал над поддержанием уровня прямой и обратной совместимости в моих программах на C ++, пока мне, в конечном счете, не пришлось делать из этого библиотечный инструментарий , который я готовлю к выпуску , уже выпущен. В общем, до тех пор, пока вы принимаете, что вы не получите «идеальной» прямой совместимости ни в функциях (некоторые вещи просто не могут быть эмулированы в прямом направлении), ни в синтаксисе (вам, вероятно, придется использовать макросы, альтернативные пространства имен для некоторые вещи) тогда у вас все готово.
Существует множество функций, которые можно эмулировать в C ++ 03 на уровне, достаточном для практического использования, и без всяких хлопот, которые возникают, например: Boost. Черт, даже предложение по стандартам C ++ nullptr
предлагает бэкпорт C ++ 03. И еще есть TR1, например, для всего C ++ 11, но «у нас были предварительные просмотры» в течение многих лет. Мало того, некоторые функции C ++ 14, такие как варианты assert, прозрачные функторы и optional
могут быть реализованы в C ++ 03!
Единственные две вещи, которые я знаю, которые не могут быть полностью перенесены, - это шаблоны constexpr и variadic.
Что касается всего вопроса добавления чего-либо в пространство имен std
, я считаю, что это не имеет значения - вообще. Вспомните Boost, одну из наиболее важных и актуальных библиотек C ++, и их реализацию TR1: Boost.Tr1. Если вы хотите улучшить C ++, сделать его более совместимым с C ++ 11, то по определению вы превращаете его в нечто, не являющееся C ++ 03, поэтому блокирование себя над стандартом, которого вы намерены избегать или оставить позади, в любом случае Проще говоря, контрпродуктивно. Пуристы будут жаловаться, но по определению не нужно заботиться о них.
Конечно, то, что вы не будете следовать (03) Стандарту, вовсе не означает, что вы не можете попытаться или будете радостно его нарушать. Не в этом дело. До тех пор, пока вы очень тщательно следите за тем, что добавляется в std
пространство имен, и имеете контроль над средами, в которых используется ваше программное обеспечение (т. Е .: проводите тестирование!), Никакого необратимого вреда не должно быть вообще. Если возможно, определите все в отдельном пространстве имен и добавьте только using
директивы в пространство имен, std
чтобы вы не добавляли туда ничего, кроме того, что «абсолютно» нужно было бы ввести. Что, IINM, более или менее то, что делает Boost.TR1.
Обновление (2013) : в качестве запроса исходного вопроса и просмотра некоторых комментариев, которые я не могу добавить из-за отсутствия повторений, приведен список функций C ++ 11 и C ++ 14 и их степень переносимости. до C ++ 03:
nullptr
: полностью реализуемо с учетом официального бэкпорта комитета; вам, вероятно, придется также предоставить некоторые специализации type_traits, чтобы он распознавался как «нативный» тип.
forward_list
: полностью реализуемо, хотя поддержка распределителя зависит от того, что может обеспечить ваша реализация Tr1.
- Новые алгоритмы (partition_copy и т. Д.): Полностью реализуемы.
- Контейнерные конструкции из последовательностей скобок (например :)
vector<int> v = {1, 2, 3, 4};
: полностью реализуемы, хотя и более многословны, чем хотелось бы.
static_assert
: почти полностью реализуемо при реализации в виде макроса (вам нужно быть осторожным только с запятыми).
unique_ptr
: почти полностью реализуем, но вам также понадобится поддержка вызова кода (для хранения их в контейнерах и т. д.); смотрите ниже, хотя.
- rvalue-reference: почти полностью реализуемо в зависимости от того, сколько вы ожидаете получить от них (например: Boost Move).
- Итерация по каждому элементу: почти полностью реализуема, синтаксис будет несколько отличаться.
- использование локальных функций в качестве аргументов (например, для преобразования): почти полностью реализуемо, но синтаксис будет достаточно отличаться - например, локальные функции не определяются на месте вызова, а прямо перед этим.
- операторы явного преобразования: реализуемые на практических уровнях (получение явного преобразования), см. « явный_каст» в Imperfect C ++ ; но интеграция с языковыми функциями, такими как,
static_cast<>
может быть почти невозможна.
- переадресация аргументов: реализуется на практических уровнях, указанных выше для rvalue-ссылок, но вам нужно будет обеспечить N перегрузок для ваших функций, принимающих пересылаемые аргументы.
- двигаться: реализуемо на практических уровнях (см. два выше). Конечно, вам придется использовать контейнеры-модификаторы и объекты, чтобы получить прибыль от этого.
- Распределители с областью видимости: Реально не реализуемы, если ваша реализация Tr1 не может помочь.
- Типы многобайтовых символов: Реально не реализуемы, если ваш Tr1 не может вас поддержать. Но для предполагаемой цели лучше полагаться на библиотеку, специально предназначенную для решения этой проблемы, такую как ICU, даже если используется C ++ 11.
- Variadic списки аргументов: реализуются с некоторыми хлопотами, обратите внимание на переадресацию аргументов.
noexcept
: зависит от возможностей вашего компилятора.
- Новая
auto
семантика и decltype
: зависит от особенностей вашего компилятора - например .: __typeof__
.
- целочисленные типы (
int16_t
и т. д.): зависит от возможностей вашего компилятора или вы можете делегировать его в Portable stdint.h.
- Атрибуты типа: зависит от возможностей вашего компилятора.
- Список инициализаторов: Насколько мне известно, это невозможно реализовать; однако, если вы хотите инициализировать контейнеры с последовательностями, см. выше в разделе «конструкции контейнера».
- Псевдоним шаблона: насколько мне известно, он не реализуем, но в любом случае это ненужная функция, и у нас
::type
всегда были шаблоны
- Шаблоны Variadic: Насколько мне известно, не реализуемы; закрытие - аргумент шаблона по умолчанию, который требует N специализаций и т. д.
constexpr
Насколько мне известно, это невозможно осуществить.
- Унифицированная инициализация: Насколько мне известно, не реализуемо, но гарантированная инициализация -конструктора по умолчанию может быть реализована в стиле Boost-initialized.
- C ++ 14
dynarray
: полностью реализуемо.
- C ++ 14
optional<>
: практически полностью реализуем, если ваш компилятор C ++ 03 поддерживает настройки выравнивания.
- Прозрачные функторы C ++ 14: почти полностью реализуемы, но вашему клиентскому коду, вероятно, придется явно использовать, например,
std::less<void>
чтобы заставить его работать.
- C ++ 14 новых вариантов утверждений (таких как
assure
): полностью реализуемых, если вы хотите утверждений , почти полностью реализуемых, если вы хотите вместо этого включить броски.
- Расширения кортежей C ++ 14 (получить элемент кортежа по типу): полностью реализуемы, и вы можете даже заставить его не скомпилироваться с точными случаями, описанными в предложении функции.
(Отказ от ответственности: некоторые из этих функций реализованы в моей библиотеке бэкпортов C ++, которую я связал выше, поэтому я думаю, что знаю, о чем говорю, когда говорю «полностью» или «почти полностью».)