c++ - 为什么 range-v3 将其函数对象放入内联命名空间?

标签 c++ c++11 range-v3 inline-namespaces

在 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/

相关文章:

c++11 - C++ 中的集合

c++ - range-v3:使用定界符连接管道范围

c++ - 从魔数(Magic Number)到 int 或 long 的重载解析(在 range-v3 中)

c++ - 我的 findContours() 函数在具有不同 dpi 的图像上表现异常

c++ - aio_write() 总是失败并出现错误 EINVAL

c++ - 一个简单的 std::shared_ptr 构造案例的段错误

c++ - 为什么有变异的 Boost.Range 算法的 const 重载?

c++ - Djikstra的实现似乎与理论复杂性不符

c++ - C++ 中构造函数注入(inject)的高级配置

c++ - 为什么add函数在c++ 11线程中没有效果?