为什么 std::literals 运算符在包含对应的 header 时不会自动导出?

Why does std::literals operators not automatically export when include their correspond header?

std::literals命名空间中有一些字面运算符和它们对应的header如operator""soperator""sv

我想知道为什么这些运算符在包含相应的 header 时不会自动导出,因为它们不会相互冲突或 user-defined 必须以下划线开头的文字运算符,通常像我这样的用户想要在包含 header.

时使用它们

如果 using std::string_literals::operator""s; 已经在 <string> header 以及其他库中,那就太好了:

#include <string> // automatically export the literal operators
#include <chrono> // automatically export the literal operators
int main() {
  auto str = "hello world"s;
  auto sec = 10s;
}

我看不出有什么坏处。为什么委员会不喜欢这样?它有什么问题或者这是一种不好的做法吗?

在 C++ 中,using 声明 无法 撤消。一旦它在那里,它后面的每一段代码(在它的范围内)都会有它的名称查找规则受该指令的影响。因此,全局 using 语句有些危险。它在 header 中更加危险,因为这将固有地影响包含 header(包括任何 header 的每个文件的行为 之后 header).

因此,C++ headers 不会将名称放入全局命名空间(C 标准库名称和不能命名空间的宏除外)。但是,只有在没有名称空间范围的情况下可以访问 UDL 时,才能使用 UDL。因此,公开 UDL 的标准习惯用法是坚持,如果您想在某些本地代码中使用文字,正确使用的习惯用法是自己编写 using 声明。你希望这些在具有 using 范围的地方,如函数定义, 而不是 全局或 namespace 范围内。

在使用 C++20 模块的代码库中,处理这些事情要容易得多,因为导入模块只会泄漏 using 指令,前提是您明确选择从该模块导出它。因此,在模块中全局声明这样的指令不一定会破坏包含该模块的任何代码。