加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 运算符超载cl和g不同的输出

发布时间:2020-12-16 03:15:47 所属栏目:百科 来源:网络整理
导读:使用这个示例程序,我观察到g和clang中的不同行为 foo.h中: #include iostreamnamespace Bar{class Foo{public: Foo(int x) : _x(x) {} int x() const { return _x; }private: int _x;};}std::ostream operator (std::ostream os,const Bar::Foo* foo); Foo.
使用这个示例程序,我观察到g和clang中的不同行为

foo.h中:

#include <iostream>

namespace Bar
{

class Foo
{
public:

    Foo(int x) : _x(x)
    {}

    int x() const
    {
        return _x;
    }

private:

    int _x;
};

}

std::ostream& operator <<(std::ostream& os,const Bar::Foo* foo);

Foo.cpp中

#include <Foo.h>

using namespace std;

ostream& operator <<(ostream& os,const Bar::Foo* foo)
{
    return os << foo->x();
}

main.cpp中

#include <iostream>

using namespace std;

template<typename T>
void print(const T& t)
{
    cout << t << endl;
}

#include <Foo.h>

int main(int argc,char** argv)
{
    Bar::Foo* foo = new Bar::Foo(5);
    print(foo);
}

用俚语和g编译产生不同的结果:

air:~ jose$clang++ Foo.cpp main.cpp -I.
air:~ jose$./a.out
0x7ff9e84000e0
air:~ jose$g++ Foo.cpp main.cpp -I.
air:~ jose$./a.out
5

哪一个是正确的,为什么?

解决方法

在这种特殊情况下,cl声是正确的.

问题是如何在模板打印中执行查找.在表达式中,打印对运算符<<是依赖的依赖名称的名称解析在14.6.4中处理:

In resolving dependent names,names from the following sources are considered:

— Declarations that are visible at the point of definition of the template.

— Declarations from namespaces associated with the types of the function arguments both from the instantiation context (14.6.4.1) and from the definition context.

在您的情况下,您的运算符的声明在模板定义点不可见,因为标题之后包含,并且它不存在于函数参数的任何关联命名空间中(即:: std for: :std :: ostream and :: Bar for :: Bar :: Foo *),所以它不会被找到.

现在,:: std中有一个重载,它占用一个void *,这将由Argument Dependent Lookup找到. :: Bar :: Foo *将被转换为一个void *,并打印地址.

也就是说,在标准兼容的编译器中.

我忘了在这里添加,只留在评论中,但它是足够重要的:

始终在同一个名称空间中定义适用于您的类型的运算符,该名称空间中包含它们应用的类型.让论据依赖查找对你来说是个魔术.它是专门为了这个特殊目的而设计的,使用它.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读