C ++ - “using”关键字或使用带有范围解析运算符的命名空间名称

时间:2016-12-22 03:59:13

标签: c++ namespaces using scope-resolution

使用这种方式编写C ++中的各种程序而不使用范围解析运算符:

#include <iostream>
#include <string>

int main()
{
std::string name = "My Name";
std::cout << name << std::endl;

return 0;
}

我也看到使用“使用”关键字:

#include <iostream>
#include <string>
using namespace std;
int main()
{
string name = "My Name";
cout << name << endl;

return 0;
}

出于效率原因哪一个更好?

2 个答案:

答案 0 :(得分:6)

假设最终找到相同的名称,效率是相同的:独立于函数名称的拼写方式,调用相同的函数。主要区别在于如何定位名称。使用完全限定可以防止例如依赖于参数的查找,因此更容易理解。

当然,当你确实有一个自定义点时,你想要使用一个非限定调用来进行依赖于参数的查找。如果不需要自定义点的默认实现那里不需要using声明甚至using指令。不正确使用自定义点 会对性能产生负面影响。例如,使用swap()时,要使用名称限定:

template <typename T>
void some_function(T& v1, T& v2) {
    std::swap(v1, v2); // <--- this is bad! It uses the default implementation

    using std::swap;   // make a default implementation visible
    swap(v1, v2);      // <--- this is better: if it exists uses T's swap()
}

如果T具有自定义swap(),则可能比std::swap()更有效,这可能会导致值v1v2的副本。对于已启用移动的类型T,差异并非如此糟糕,但仍然可能很大。当然,这里的问题不是使用资格或没有资格,而是调用函数的两种方法可能会导致找到不同的函数,这取决于swap()是否为{T重载1}}。

顺便说一句,如果你对效率感兴趣,do not use std::endl

答案 1 :(得分:1)

这两个程序应该生成相同的可执行代码。在C ++中,名称查找在编译时发生,而不是在运行时发生,因此编译器在编译期间找到名称,然后在以后没有任何更改。没有运行时评估,因此用于查找给定名称的语法不会影响程序的效率。

正如Dietmar所说,选择语法可能会导致找到不同的名称,这可能会改变行为,但假设找到相同的名称,效率就没有差别。