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

时间:2014-12-18 22:04:08

标签: c++ c++14

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

这是什么原因?

1 个答案:

答案 0 :(得分:21)

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

  1. 用户仅使用using namespace std;来获取相应的文字是不可取的。在特定于名称空间的文件中声明文字不会导致问题。
  2. 根据域名,可能需要使用s作为其他内容的后缀。已经有另一个后缀s表示秒,但它们并没有真正发生冲突。
  3. 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;
    显然,如果委员会认为这个想法可以用文字后缀污染全局命名空间,那么委员会就不会付出太多努力,尽管它们甚至不能与任何用户文字后缀冲突。