【问题标题】:Why is operator""s hidden in a namespace?为什么 operator"" 隐藏在命名空间中?
【发布时间】:2015-02-17 19:49:38
【问题描述】:

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

这是什么原因?

【问题讨论】:

标签: c++ c++14


【解决方案1】:

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

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

video of STL's CppCon 2014 talk(由 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;

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

【讨论】:

  • 我不相信。用户非标准库代码无论如何都不能声明operator""s,或者可以吗?
  • @milleniumbug:正确:用户定义的文字需要以 _ 开头。解决的冲突不是用户代码,而是其他标准库类。顺便说一下,我想不出一个令人信服的例子,但是一旦我们有了一个网络库,使用"127.0.0.1:80"s 创建一个套接字可能会很酷。 ...和另一个论点,不想强制使用using namespace std; 污染代码仍然成立:据我所知,您不能仅针对文字运算符进行选择性using-声明。
  • @milleniumbug 提议的string_view""s 文字的另一个潜在候选者,尽管它过去也使用""sv 以避免冲突。 (在当前草案中它根本没有文字运算符。)不知道将保留哪个解决方案(如果有)(例如,不同命名空间中的并发 ""s 文字或其他)。
  • 这个设计决策的另一面是,没有合理的方式在头文件中使用标准的用户定义文字而不违反“头文件中没有 using 指令”指南。
猜你喜欢
  • 2018-08-09
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-13
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
相关资源
最近更新 更多