В поисках разъяснений по встроенному пространству имен

В 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 в одиночку), это позволяет конечным пользователям специализироваться, не зная деталей inlined namespaces.

Другие вопросы по тегам