【问题标题】:Is `using namespace std::literals` safe?`using namespace std::literals` 安全吗?
【发布时间】:2018-03-27 01:42:41
【问题描述】:

通常,全局范围内的using namespaceconsidered as a bad practice。但是,根据cppreference,不以下划线(_)开头的标识符在用户定义文字的情况下保留给标准库。

用作将调用此函数的用户定义文字的 ud-suffix 的标识符。必须以下划线_开头:不以下划线开头的后缀是为标准库提供的文字运算符保留的。

这是否意味着我可以在全局范围内安全地执行using namespace std::literals;

【问题讨论】:

  • 我不确定“安全”是否正确。我不喜欢using namespace。在我的所有#include 指令之后,我总是选择我正在使用的特定标识符。 using std::literals::string_literals::operator""s
  • "通常,using namespace 在全局范围内被认为是一种不好的做法" - 不完全是。不好的做法是using namespace std,而不是using namespace
  • @RemyLebeau 虽然链接的问题是关于namespace std,但它不好的原因也适用于任何其他命名空间;命名空间的目的是防止名称冲突,using namespace 打破它。 (链接问题的接受答案解释了这一点。)我的问题的重点是using namespace std::literals 是否也会产生名称冲突。

标签: c++ user-defined-literals


【解决方案1】:

这些用户定义的文字是相当新的。您必须了解这里的标准机构;他们没有实际使用的经验(不像Boost)。所以他们想出了一个保守的方法:一方面,预定义的后缀在namespace std,另一方面,用户定义的文字必须以_开头。

这确实在中间留下了一个开放空间:不以_ 开头但在全局命名空间中定义的后缀。随着我们对现有文字的积累经验,可能会决定谁来定义这些文字。

因此,为了让您的代码经得起未来考验,无论在未来标准中做出何种选择,您都不应该给其他人带来太多问题。但这是否意味着“避免在全局命名空间中使用 using”?不,每个翻译单位都可以做出自己的选择。在你自己的 .cpp 文件中,做你喜欢的事。但您不应影响其他翻译单元。因此实际的规则是:

using namespace std::literals 在标头中不安全

【讨论】:

    【解决方案2】:

    从标准的角度来看,当他们说标准库保留了某些名称时,如果您违反约定,我会将其解释为不保证已定义的行为。另一方面,某些编译器可能不会要求您对违反规定的约定负责。例如,gcc 给出的是警告,而不是错误,因为它没有以下划线开头的文字运算符标识符。

    这里更好的表述不是是否包括

    using namespace std::literals;
    

    在全局范围内是一种安全的做法,但它是否是一种好的防御性编程策略。将using namespace foo 放在全局范围内不是防御性编程,因为这样做违背了命名空间的目的,至少在一定程度上是这样。

    现在,鉴于您的特定代码库,您这样做可能永远不会遇到问题。但这只是由你来判断。如果您打算与他人共享您的代码,我建议您进行防御性编程,这样您的代码的不知情用户将不会有机会遇到意外情况(即使他们不遵循所有约定,或者如果将来修改标准)。

    【讨论】:

    • 在防御性编程方面相当合理。但是语言律师的问题仍然存在,即std::literals 中的名称是否永远不会与其他用户定义的名称发生冲突,或者在合法的 c++ 中没有?
    • 同意。如果所有标准文字都以_开头,但所有用户定义的文字do,那么我看不出它们会如何发生冲突。但这是一个很大的如果
    猜你喜欢
    • 1970-01-01
    • 2011-10-14
    • 2011-09-22
    • 2016-02-27
    • 2017-04-20
    • 1970-01-01
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多