c++ - 为什么我必须写 std::cout 而不是 std::<<

标签 c++

为什么一定要写std::cout也不是std::<<在这样的一行代码中:

#include <iostream>

int main() {
    std::cout << "Hello, world!";
    return 0;
}

cout来自 std图书馆,而不是 <<通常用来做位移?那么,为什么我不必编写范围运算符 ::也在 << 之前,既然它也有其他含义吗?编译器如何知道 std::cout 之后, <<是什么意思?

最佳答案

首先,编译器会查看 << 左右的类型。 . std::coutstd::ostream 类型,字符串字面量的类型为 array of 15 const char 。由于左边是类类型,它将搜索名为 operator<< 的函数。 .问题是,它会在哪里?

查找此名称 operator<<是所谓的非限定查找,因为函数名没有限定,如 std::operator<< .函数名称的非限定查找调用依赖于参数的查找。与参数相关的查找将在与参数类型关联的类和命名空间中进行搜索。

当您包含 <iostream> 时, 签名的自由函数

template<typename traits>
std::basic_ostream<char, traits>& operator<<(std::basic_ostream<char, traits>&,
                                             const char*);

已在命名空间 std 中声明.此命名空间与 std::cout 的类型相关联。 ,因此会找到这个函数。

std::ostream只是 std::basic_ostream<char, std::char_traits<char>> 的 typedef , 以及 15 的数组const char 可以隐式转换为 char const* (指向数组的第一个元素)。因此,可以使用两种参数类型调用此函数。

operator<< 还有其他重载,但我上面提到的函数是参数类型和本例中选择的最匹配的函数。


参数依赖查找的简单示例:

namespace my_namespace
{
    struct X {};

    void find_me(X) {}
}

int main()
{
    my_namespace::X x;
    find_me(x);       // finds my_namespace::find_me because of the argument type
}

注意由于此函数是一个运算符,因此实际查找要复杂一些。它通过第一个参数范围内的限定查找(如果它是类类型)进行查找,即作为成员函数。 另外,执行非限定查找,但忽略所有成员函数。结果略有不同,因为非限定查找实际上就像一个两步过程,其中依赖于参数的查找是第二步。如果第一步找到成员函数,则不执行第二步,即使用参数相关查找。

比较:

namespace my_namespace
{
    struct X
    {
        void find_me(X, int) {}
        void search();
    };
    void find_me(X, double) {}

    void X::search() {
        find_me(*this, 2.5); // only finds X::find_me(int)
        // pure unqualified lookup (1st step) finds the member function
        // argument-dependent lookup is not performed
    }
}

到:

namespace my_namespace
{
    struct X
    {
        void operator<<(int) {}
        void search();
    };
    void operator<<(X, double) {}

    void X::search() {
        *this << 2.5; // find both because both steps are always performed
        // and overload resolution selects the free function
    }
}

关于c++ - 为什么我必须写 std::cout 而不是 std::<<,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19122575/

相关文章:

c++ - 在 Visual C++ 2013 中分配给 const 引用

C++ 复制构造函数和运算符

c++ - v8::ObjectTemplate::SetAccessor 和 v8::Template::Set - 区别

c++ - 为什么 GCC --gc-sections 和 -ffunction-sections 不起作用? (构建)

python - 如何将二维数组从 C 传递给 Python

c++ - Qt 框架 : How to display a QGraphicsView in a layout?

c++ - C++ 函数中返回字符串中最常见字符的错误。多字节字符?

c++ - 如何使用 C++ 获取 SQL SERVER 安装路径?

c++ - 在 omp parallel for 循环中使用 unique_ptr<CCfits::FITS> 导致 SEG.FAULT

c++ - 在 C++ 中将两个类交织在一起是一种不好的做法吗?