В cppreference, найден следующий текст:
Каждый член встроенного пространства имен может быть частично специализированным,
явно конкретизированы или явно специализированы, как если бы это было
член вмещающего пространства имен.Примечание: правило о специализациях допускает управление версиями библиотеки:
различные реализации шаблона библиотеки могут быть определены в
различные встроенные пространства имен, в то же время позволяя пользователю расширять
родительское пространство имен с явной специализацией основного
шаблон.
Что означают эти заявления? Может кто-нибудь объяснить с помощью простого примера?
Рассмотрим глупый пример:
#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.
Других решений пока нет …