c++ - 库和命名空间之间的关系是什么?

标签 c++ input namespaces output iostream

刚开始拼贴,我是编程世界的新手。因此,在我学习 C++ 时,我遇到了一个让我无法理解的问题:“为什么我需要在我的代码中包含“使用命名空间 std”才能在我已经获得 iostream 的情况下进行写入或读取? ,因为我被告知在 iostream 库中已经定义了“cin/cout”,但我注意到如果我单独编写这些行之一,它将产生编译错误。因此,iostream 和“std”命名空间之间的关系是什么......有人可以解释一下吗?谢谢! <3

最佳答案

#include 与使用
简单来说:

#include <iostream> // include the header

int main() {
    // now you can use stuff declared in that header
    std::cout << "Hello world" << std::endl;

    // if you are lazy you can "use" things:
    using std::cout;
    using std::endl;
    cout << "Hello World" << endl;
}
你做不是 不得不写using namespace std; !适合这样做的情况非常罕见,而真正造成巨大伤害的情况却非常频繁,所以根据经验,您可以记住:永远不要使用它!详情请看这里:Why is “using namespace std;” considered bad practice? .重要的是要意识到完全限定名称之间的区别,std::cout ,而不是完全限定名称,cout , 不仅仅是输入 5 个字符或多或少(请继续阅读...)。

库与命名空间

What's the relation between libraries and namespaces?


标准库将所有内容放在 std 中命名空间。命名空间有助于将事物分开。不同的库可以包含 other_namespace::vector并且不会与 std::vector 混淆因为我们有命名空间。

非常酷的东西
使用命名空间的一个更深层次的原因是 Argument Dependent Lookup .我将尝试用一个简单的例子来解释。假设您正在使用一个带有一些函数模板的库,该函数模板对您必须提供的类型的对象执行某些操作:
namespace library {
    template<typename T>
    void do_something(T& a,T& b){
        std::cout << "wrong...\n";
        std::swap(a,b);    // (1) 
        std::cout << "correct\n";
        using std::swap;   
        swap(a,b);         // (2)
    }
}
我拿了两个对象并交换了它们两次。你必须忍受我一秒钟才能理解为什么(1)是错误的,只有(2)是正确的。现在我们有一个库函数模板,要使用它我们需要一些类型 T :
namespace A {
    struct foo{};
    void swap(foo& a,foo& b) {
        std::cout << "A::swap" << "\n";
    }
}
想象 foo是这样的,我们知道比 std::swap 更好的方法至 swap到实例。其实foo是空的,所以到 swap两个对象我们什么都不做。
让我们回顾一下:有 std::swap标准库附带的。有人写了一个我们想要使用的库(名为 library )。我们希望库代码调用 A::swap而不是 std::swap .图书馆作者甚至不知道 A::swap存在。
连同以上 Alibrary ,这段代码
int main() {
    A::foo a,b;
    library::do_something(a,b);
}
将打印:
wrong...
correct
A::swap
Live Example .发生了什么?这一行:
std::swap(a,b);    // (1) 
电话std::swap , 毫无疑问。不是我们想要的。我们希望库代码调用我们的 A::swap .
现在这个:
using std::swap;   
swap(a,b);         // (2)
第一行拉取名字swap来自 std进入函数范围。在第二行中,ADL 终于开始了,因为它说 swap不是 std::swap .简而言之,ADL 是:ab来自命名空间 A ,所以当编译器搜索所有可能的 swap 时s 它也在 A 中搜索.如果它在 A 中找到一个然后它调用它(如果它在 A 中没有找到,还有来自 swapstd )。因此只有 (2) 调用我们的自定义交换。
这仅适用于命名空间。 “很酷的东西”是库作者不需要知道关于您的命名空间的任何信息,但他们的库代码仍然会从您的命名空间调用您的函数(如果它存在)。
我应该注意,并非所有代码都是通用库代码。通常,您想编写代码,其中您知道每个细节中发生了什么,您想知道调用了哪些函数。通常,您不希望您的代码根据包含与否的特定 header 而表现不同。因此,大量代码最好使用完全限定的函数调用:std::foo .

结论
我希望我能说服你,命名空间不仅仅是或多或少地输入一些字符。 using namespace std;因为懒惰完全忽略了命名空间的意义。另一方面,通过 using std::foo; foo(); 将名称拉入范围是
完全没问题并启用 ADL。

关于c++ - 库和命名空间之间的关系是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63622089/

相关文章:

C++ 在 vector 中查找

javascript - Firefox 没有在周围的 div 上注册点击事件

c++ - 按位操作,获得更大值(value)

c++ - 在 Linsched 中使用 task_struct

c - C 中的 Char 数组

java - 使用 NumberPicker 作为输入法而不是标准键盘

c# - (关于最佳实践的问题)为什么默认有 "using System.Text"?

c# - 为整个项目全局命名空间别名

c# - .NET (C#) 将消息从自定义控件传递到主应用程序

c++ - Cereal 序列化和多态性