В поисках разъяснений по встроенному пространству имен
В cppreference, следующий текст найден:
Каждый член встроенного пространства имен может быть частично специализированным, явно реализованным или явно специализированным, как если бы он был членом окружающего пространства имен.
Примечание: правило о специализациях допускает управление версиями библиотеки: разные реализации шаблона библиотеки могут быть определены в разных встроенных пространствах имен, но при этом пользователь может расширять родительское пространство имен с явной специализацией основного шаблона.
Что означают эти заявления? Может кто-нибудь объяснить с помощью простого примера?
1 ответ
Рассмотрим глупый пример:
#include <iostream>
namespace foo {
inline namespace v1 {
template <typename T>
void bar(T t) {
(void) t;
std::cout << "Generic bar\n";
}
}
template <>
void bar<int>(int v) {
(void) v;
std::cout << "Specialized bar\n";
}
}
int main() {
foo::bar(12);
foo::v1::bar(12);
foo::bar(12.0);
return 0;
}
Если вы запустите это, вы получите следующий вывод:
Specialized bar
Specialized bar
Generic bar
Это потому что зовет foo::bar
с int
специализируется на foo
хотя реализация по умолчанию существует в foo::v1
,
Этот пример бесполезен, но рассмотрим сценарий, в котором вы хотели бы специализировать template
функция или class
во внешней библиотеке (включая stl). Вы не знаете, если vector
является членом std
или же std::cxx11
(libC++ использует std::__1
для многих вещей). С inline namespace
способ предоставления версий на уровне API (например, вы меняете inline namespace
в v2
и уходи v1
в одиночку), это позволяет конечным пользователям специализироваться, не зная деталей inline
d namespace
s.