为什么我必须写std :: cout,而不是std ::<< [英] Why I have to write std::cout and not also std::<<

查看:634
本文介绍了为什么我必须写std :: cout,而不是std ::<<的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我必须写 std :: cout ,而不是 std ::<< 一行代码如下:

  #include< iostream> 

int main(){
std :: cout< 你好,世界!;
return 0;
}

cout std 库,而不是< 通常用于做位移?所以,为什么我不必在< 之前编写范围运算符 :: 也用于另一个意思?编译器如何知道 std :: cout < 意味着另一件事情?

解决方案

首先,编译器将查看<< std :: cout 的类型为 std :: ostream ,字符串文字的类型为 array of 15 const char 。由于左边是类类型,它将搜索一个名为 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>> 和<15> const char 数组可以隐式转换为 char const * 指向数组的第一个元素)。

还有其他重载 operator<< ,但上面提到的函数是参数类型和在这种情况下选择的参数类型的最佳匹配。






A参数相关查找的简单示例:

 命名空间my_namespace 
{
struct X {};

void find_me(X){}
}

int main()
{
my_namespace :: X x;
find_me(x); //查找my_namespace :: find_me因为参数类型
}






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



比较: / p>

 命名空间my_namespace 
{
struct X
{
void find_me int){}
void search();
};
void find_me(X,double){}

void X :: search(){
find_me(* this,2.5); //仅查找X :: find_me(int)
//纯无限查找(第一步)查找成员函数
//不执行与参数相关的查找
}
}

至:

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

void X :: search(){
* this< 2.5; //找到它们,因为两个步骤总是执行
//并且重载解决方案选择自由函数
}
}


Why do I have to write std::cout and not also std::<< in a line of code like this:

#include <iostream>

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

cout comes from std library, and isn't << usually used to do bits shifting? So, why don't I have to write the scope operator :: also before <<, since it is used also with another meaning? How the compiler knows that after std::cout, << means another thing?

解决方案

First, the compiler will look at the types to the left and right of <<. std::cout is of type std::ostream, the string literal is of type array of 15 const char. As the left is of class type, it will search for a function named operator<<. The question is, where will it look?

The lookup for this name operator<< is a so-called unqualified lookup, because the function name isn't qualified like std::operator<<. Unqualified lookup for function names invokes argument-dependent lookup. The argument-dependent lookup will search in the classes and namespaces associated with the argument types.

When you include <iostream>, a free function of the signature

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

has been declared in namespace std. This namespace is associated with the type of std::cout, therefore this function will be found.

std::ostream is just a typedef for std::basic_ostream<char, std::char_traits<char>>, and the array of 15 const char can be converted implicitly to a char const* (pointing to the first element of the array). Therefore, this function can be called with the two argument types.

There are other overloads of operator<<, but the function I mentioned above is the best match for the argument types and the one selected in this case.


A simple example of argument-dependent lookup:

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
}


N.B. As this function is a operator, the actual lookup is a bit more complex. It is looked up via qualified lookup in the scope of the first argument (if that's of class type), i.e. as a member function. Additionally, unqualified lookup is performed, but ignoring all member functions. The result is slightly different, because unqualified lookup is actually like a two-step procedure, where argument-dependent lookup is the second step. If the first step finds a member function, the second step is not performed, i.e. argument-dependent lookup is not used.

Compare:

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
    }
}

to:

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
    }
}

这篇关于为什么我必须写std :: cout,而不是std ::&lt;&lt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆