为什么运算符 " " 隐藏在命名空间中?

Why is operator""s hidden in a namespace?

本文关键字:命名空间 隐藏 运算符 为什么      更新时间:2023-10-16

为了将operator""s用于std::string,您必须执行using namespace std::string_literals。但是,不以_开头的用户定义文本是保留的,因此可能的冲突不能成为借口。另一个operator""s来自std::chrono但那是针对 int 文字的,所以那里也没有冲突。

这是什么原因呢?

实际上有两个原因将文本放入命名空间:

  1. 用户使用using namespace std;只是为了获取相应的文本被认为是不可取的。在特定于这些文本的命名空间中声明文本不会导致问题。
  2. 根据域的不同,可能需要使用 s 作为其他内容的后缀。已经有另一个后缀s表示秒,但它们并没有真正冲突。

STL的CppCon 2014演讲视频中(由remyable发表在评论中(,Stephan T. Lavavej解释了C++14中文字的整体设计,很明显它们不应该在全局命名空间中!相反,标准库中的文本后缀位于inline命名空间的层次结构中,使用户可以对可用的文本进行精细控制。例如,字符串的文字后缀是这样声明的(21.3 [string.classes] 第 1 段(:

namespace std {
    inline namespace literals {
        inline namespace string_literals {
            string operator"" s(char const* str, size_t len);
        }
    }
}

这种inline命名空间的层次结构使用户可以获得文本后缀的适当选择:

  • using namespace std; - 您可以在标准C++库中获取所有内容,包括文字后缀,没有任何资格。
  • using namespace std::literals; - 您将获得标准C++库中定义的所有文字后缀。
  • using namespace std::string_literals; - 您将获得适用于字符串的所有文字后缀。
  • using namespace std::literals::string_literals; - 是的,你可以这样做,但你真的不应该这样做:这相当于using namespace std::string_literals;.

显然,如果委员会认为用文字后缀污染全局命名空间的想法是可行的,那么它就不会付出那么多努力,尽管它们甚至不能与任何用户文字后缀冲突。