In range-v3, all of the functions are really global function objects in an inline namespace:
#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
What is the purpose of the function_objects
namespace? It is not referenced anywhere else in the library as far as I can tell.
Based on Casey's comments on the PR that led to this addition (thanks Justin), the
inline namespace
is necessary for something like this to work:If the customization point object
swap
(at#1
) were not in its own namespace, there would be a name clash between the cpo and the non-memberfriend
declared for typeS
(at#2
). Those must be in different namespaces.Putting the CPO in an inline namespace is sufficient because regular unqualified or qualified lookup will never find the swap at
#2
- it will only be found by ADL, which only happens withinswap_fn::operator()
.Yeah, this is pretty cool. And complex.