在 range-v3 中,所有函数实际上都是 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
function_objects
命名空间的用途是什么?据我所知,它在图书馆的其他任何地方都没有被引用。
最佳答案
基于 Casey 对 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 中::运算符()
。
是的,这很酷。并且复杂。
关于c++ - 为什么 range-v3 将其函数对象放入内联命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50010074/