Одной из причин, которую часто упускают из виду, является то, что просто изменяя одну строку кода для выбора одного пространства имен над другим, вы можете выбрать альтернативный набор функций / переменных / типов / констант - например, другую версию протокола илимногопоточная и многопоточная поддержка, поддержка ОС для платформы X или Y - скомпилируйте и запустите.Такой же эффект может быть достигнут путем включения заголовка с разными объявлениями или с #defines
и #ifdefs
, но это грубо влияет на всю единицу перевода, и при связывании разных версий вы можете получить неопределенное поведение.С помощью пространств имен вы можете делать выборки с помощью пространства имен, которые применяются только в активном пространстве имен, или делать это с помощью псевдонима пространства имен, чтобы они применялись только там, где используется этот псевдоним, но на самом деле они разрешаются в различные символы компоновщика, поэтому могут быть объединены безнеопределенное поведение.Это можно использовать способом, аналогичным шаблонным политикам, но эффект более неявный, автоматический и распространяющийся - очень мощная языковая функция.
ОБНОВЛЕНИЕ: обращение к комментарию marcv81 ...
Почему бы не использовать интерфейс с двумя реализациями?
"интерфейс + реализации" - это концептуально то, что делает выбор пространства имен для псевдонима выше, но если вы имеете в виду время выполнения полиморфизм и виртуальная диспетчеризация:
результирующая библиотека или исполняемый файл не должны содержать все реализации и постоянно направлять вызовы выбранной во время выполнения
, поскольку одна реализация включена, компилятор может использовать множество оптимизаций, включая встраивание, устранение мертвого кода, и константы, отличающиеся между «реализациями», могут использоваться, например, для размеров массивов - что позволяет автоматическое выделение памяти вместо медленного динамического выделения
различные пространства имен, гаМы поддерживаем ту же семантику использования использования , но не обязаны поддерживать тот же набор сигнатур функций, что и в случае виртуальной диспетчеризации
с пространствами именВы можете предоставить пользовательские функции и шаблоны, не являющиеся членами: это невозможно при виртуальной диспетчеризации (а функции, не являющиеся членами, помогают с перегрузкой симметричного оператора - например, поддерживают 22 + my_type
, а также my_type + 22
)
разные пространства имен могут указывать разные типы для использования в определенных целях (например, хеш-функция может возвращать 32-битное значение в одном пространстве имен, но 64-битное значение в другом), но виртуальный интерфейс должен иметь объединяющие статические типы, которыеозначает неуклюжую и косвенную косвенную передачу, такую как boost::any
или boost::variant
, или наихудший выбор, когда старшие биты иногда бессмысленныобработка ошибок: с пространствами имен есть опция , чтобы просто не указыватьИдеальная функциональность в пространствах имен, где это не имеет смысла, обеспечивая принудительное выполнение необходимых усилий по переносу клиента во время компиляции