Почему range-v3 помещает свои функциональные объекты во встроенное пространство имен? - PullRequest
0 голосов
/ 24 апреля 2018

В range-v3 все функции являются действительно глобальными объектами функций в встроенном пространстве имен :

#if RANGES_CXX_INLINE_VARIABLES < RANGES_CXX_INLINE_VARIABLES_17
#define RANGES_INLINE_VARIABLE(type, name)                              \
    inline namespace function_objects                                   \
    {                                                                   \
        inline namespace                                                \
        {                                                               \
            constexpr auto &name = ::ranges::static_const<type>::value; \
        }                                                               \
    }

#else  // RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
#define RANGES_INLINE_VARIABLE(type, name) \
    inline namespace function_objects      \
    {                                      \
        inline constexpr type name{};      \
    }
#endif // RANGES_CXX_INLINE_VARIABLES

Какова цель пространства имен function_objects? Насколько я могу судить, на него нет ссылок нигде в библиотеке.

1 Ответ

0 голосов
/ 25 апреля 2018

Основываясь на комментариях Кейси о PR , который привел к этому добавлению (спасибо Джастину), inline namespace необходим для того, чтобы что-то подобное работало:

namespace N {
    namespace detail {
        // default implementation
        template <typename T> void swap(T&, T& ) { ... }

        struct swap_fn {
            template <typename T>
            void operator()(T& a, T& b) {
                swap(a, b); // unqualified call, the default is in scope
            }
        };
    }

    // the object
    inline namespace CPO { inline constexpr detail::swap_fn swap{}; } // #1

    struct S { friend void swap(S&, S&) { ... } }; // #2
}

N::S a;
N::swap(a, a); // calls the CPO, which calls the friend function

Еслиобъект точки настройки swap (на #1) не находился в своем собственном пространстве имен, между cpo и нечленом friend, объявленным для типа S (на #2), произошло бы столкновение имен.Они должны быть в разных пространствах имен.

Поместить CPO во встроенное пространство имен достаточно, потому что регулярный неквалифицированный или квалифицированный поиск никогда не найдет своп в #2 - он будет найден только ADL, что происходит только в swap_fn::operator().

Да, это круто.И сложный.

...