qri*_*kko 7 c++ namespaces using
我想知道一点关于namespace和usingC++基本上我想知道差异并弄清楚如何以最好的方式使用它.
我看到它有(至少)三种方法来解决一个类名,我不知道如何选择它们:
using namespace <namespace>using <namespace>::<what_to_use><namespace>::<what_to_use> <use_it>我想知道优势,特别是如果有一种或另一种方式涉及性能,如果它只是语法和偏好的问题,或者是否有其他事情我没有考虑过这个.
首先是using namespace指令,它带来当前命名空间中指定命名空间的所有符号名称,无论您是否需要/使用它们.当然不受欢迎.
其次是使用命名空间声明.它只会在当前命名空间中显示指定的符号名称.优点是您不必每次都输入完全限定的名称.
第三个是符号的完全限定名称.缺点是您必须在使用符号的任何位置键入完全限定名称.
显然,第二和第三是更合适的.它们中的任何一个都没有性能差异.唯一的区别是您输入的字符数量.简单地说,根据您的编码标准指定选择.
编辑:
正如@Jerry指出的那样,将声明与ADL(基于参数的查找)结合使用会导致不良影响.
你可以在我的一个答案中找到详细的解释:
关于Koenig查找如何与命名空间一起使用以及为什么它是一件好事的详细解释?
在该部分下,
为什么批评Koenig算法?
有一种(诚然,有点不常见)情况,您使用的形式确实可以产生影响,而您想要使用的形式是 using namespace foo,并且它最常应用于std命名空间(即,您在其中编写using namespace std;.
最明显的例子是您正在为用户定义类型编写排序。这可能会应用于用户也定义了自己的类型swap。
您陷入了这样一种情况:如果他们定义了交换,您想使用他们的交换,但如果他们没有定义交换,则使用 std::swap。std::swap如果您直接在代码中使用,那么std::swap即使该类型有自己定义的交换,您最终也会使用。相反,如果您直接专门为该类型指定交换,并且没有提供任何交换,则您的代码将无法编译。
为了解决这个问题,你可以这样做:
using namespace std;
template <class Iter>
void my_sort(Iter first, Iter last) {
// ...
if (*last < *first)
swap(*first, *last);
}
Run Code Online (Sandbox Code Playgroud)
这将找到专门用于被比较类型的交换(即,swap在与该类型相同的命名空间中定义的交换),如果有一个交换(通过参数相关查找),并且std::swap如果没有为该类型定义交换(通过using namespace std;)。
这可能会对性能产生影响 - 如果他们专门为其类型编写了交换,您通常可以预期这是因为通过这样做,他们可以提供更好的性能。这意味着显式指定std::swap可能有效,但可能会导致性能较差。
否则,这几乎完全是一个方便性和可读性的问题——我最喜欢给出全名(例如,std::swap),除了上面这样的情况,其中(在我编写代码时)至少有两种可能性之一可能是首选,我想给编译器足够的余地来选择正确的。
我发现使用声明/指令有用的另一次是当名称空间嵌套得非常深时。Boost(举一个明显的例子)有一些名称,如果您每次都使用完全限定名称,那么这些名称将太长而无法方便使用。对于(现在,谢天谢地,大部分已经过时的)Boost Lambda 库尤其如此,您在其中使用了诸如 之类的占位符_1,最终结果会是这样的boost::lambda::placeholders::_1(但我是凭记忆写的,所以这可能至少部分是错误的)如果您坚持使用完全限定名称。这首先就违背了使用 lambda 库的大部分目的。
| 归档时间: |
|
| 查看次数: |
1815 次 |
| 最近记录: |