STL命名规则为什么要使用那么多前置下划线?

11

例如,

template<typename _RandomAccessIterator, typename _Compare>
inline void
sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
     _Compare __comp)
{
    typedef typename iterator_traits<_RandomAccessIterator>::value_type
        _ValueType;

    // concept requirements
    __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
                                    _RandomAccessIterator>)
        __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _ValueType,
                                    _ValueType>)
        __glibcxx_requires_valid_range(__first, __last);

    if (__first != __last)
    {
        std::__introsort_loop(__first, __last,
                              std::__lg(__last - __first) * 2, __comp);
        std::__final_insertion_sort(__first, __last, __comp);
    }
}

由于这些模板位于命名空间std中,并且大小写都被使用,那么为什么需要前导下划线(单个和双个)?这只是那些开发者的一种风格吗?还是有合理的技术原因?

2个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
19

如果标准库的实现看起来像这样,使用合理的名称而不是下划线:

请考虑会发生什么。

template<typename RandomAccessIterator, typename Compare>
inline void
sort(RandomAccessIterator first, RandomAccessIterator last,
     Compare comp);
现在,如果这被包含在一个用户程序中,并且程序开头是这样的:
#define comp(X, Y) ((X) < (Y))
#include <algorithm>
comp宏定义会导致预处理器将sort声明转换为以下形式:
template<typename RandomAccessIterator, typename Compare>
inline void
sort(RandomAccessIterator first, RandomAccessIterator last,
     Compare ((X) < (Y)));
             ^^^^^^^^^^^
这段代码将无法通过编译。因为用户可以定义类似于 compCompareRandomAccessIterator 这样的宏,而且宏不会尊重命名空间、作用域或其他上下文,因此标准库必须使用带有前导下划线的丑陋名称以避免冲突。这是安全的,因为禁止用户声明任何像 __comp 这样的名称,所以不会发生冲突。这些名称被称为保留名称这不是一种编码规范,而是实现防止与任意用户定义名称冲突的唯一方式。 为了使惯例起作用,用户永远不应声明任何保留名称。您决不能为您自己的代码复制此惯例。

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,