C++ STL中单下划线与双下划线前缀的命名区分问询
我从代码可读性角度提出这个问题,不关注具体实现细节。目前没找到文章解释C++ STL里单前缀下划线、双前缀下划线、前后双下划线命名的区别,这些命名风格有没有提升可读性的特殊含义?从示例看似乎没规律:
- 单前缀下划线(_single):
using type = _Template<_Up, _Types...>; - 双前缀下划线(__double):
struct __replace_first_arg - 前后双下划线(prefixAndSuffixUnderscore):
namespace std __attribute__((__visibility__("default")))
附STL容器示例代码
e.g: 1
namespace std __attribute__((__visibility__("default"))) { class __undefined; template <typename _Tp, typename _Up> struct __replace_first_arg { }; template <template <typename, typename...> class _Template, typename _Up, typename _Tp, typename... _Types> struct __replace_first_arg<_Template<_Tp, _Types...>, _Up> { using type = _Template<_Up, _Types...>; };
e.g: 2
template <typename _InputIterator, typename _Distance> inline constexpr void __advance(_InputIterator & __i, _Distance __n, input_iterator_tag) { do { if (__builtin_is_constant_evaluated() && !bool(__n >= 0)) __builtin_unreachable(); } while (false); while (__n--) ++__i; }
注:我已经了解C++中避免前缀下划线以规避STL名称冲突的规范,此问题并非询问该内容。
回答
在GCC/libstdc++这类主流STL实现里,这些下划线命名风格主要是内部代码分层的可读性标识,不同的下划线规则对应不同的内部组件层级:
前后双下划线(xxx):
这类名称要么是C++标准预留的关键字/编译器扩展特性(比如__attribute__),要么是STL实现里和编译器深度绑定的核心标识,用来和普通内部符号区分开,一眼就能看出是和编译特性、标准强制预留相关的内容,避免和其他内部符号混淆。双前缀下划线(__xxx):
用来标识STL内部的私有工具类/函数/模板,这些是完全不对外暴露的实现细节,仅在STL内部使用。比如__replace_first_arg、__advance这类,看到双前缀下划线就知道这是STL自己用的工具,不属于用户应该接触的接口,可读性上直接划清了“用户可用”和“内部实现”的界限。单前缀下划线(_xxx):
一般用来标识STL内部的半公开/辅助型模板参数或类型别名,比如_Template、_Tp这类。这类符号虽然也是内部用,但通常是模板定义里的通用参数名,或者是在内部模板之间传递的类型标识,相比双前缀的私有工具,它们的“内部层级”稍浅,在模板实现里用来区分用户传入的参数和内部定义的辅助类型,提升模板代码的可读性。
简单来说,下划线的数量和位置是STL实现团队约定的内部代码可读性规范,用来快速区分符号的用途、层级和暴露范围,让维护STL的开发者能一眼识别符号的定位,不用去查注释就能大致了解其使用场景。
内容的提问来源于stack exchange,提问作者FredFrugal

