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

use*_*981 24 c++ c++14

为了你的使用operator""sstd::string必须这样做using namespace std::string_literals.但是不_保留用户定义的文字是保留的,因此可能的冲突不能成为借口.另一个operator""s来自std::chrono但是那是int文字,所以也没有冲突.

这是什么原因?

Die*_*ühl 22

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

  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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这种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;.

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

  • 这个设计决策的另一面是,没有合理的方法在头文件中使用标准的用户定义文字而不违反标题中的"no`using`指令"指南. (4认同)
  • @milleniumbug:正确:用户定义的文字需要以“ _”开头。解决的冲突不在于用户代码,而在于其他标准库类。暂时,我想不出有说服力的示例,但是一旦我们有了网络库,使用`“ 127.0.0.1:80"s创建套接字可能会很酷。...和另一个参数,无论如何都不想使用`using namespace std;`来强制执行污染代码:据我所知,您不能仅对文字操作符进行选择性的`using`声明。 (2认同)