首页 > 解决方案 > C++ 类外运算符实现解析为 `namespace::operator<<` 而不是 `operator<<`

问题描述

所以我正在operator<<为一个类编写重载,如下所示:

#test.hh
#pragma once
#include<iostream>
namespace ns {
    struct test {
        double d;
        test(double x): d(x) {}
        friend std::ostream& operator<<(std::ostream&, const test&);
    };
}
#test.cc
#include"./test.hh"
std::ostream& operator<<(std::ostream& os, const ns::test& a) {
    os << a.d;
    return os;
}

使用以下主要测试:

#main.cc
#include"./test.hh"
#include<iostream>
int main() {
    ns::test a(12);
    std::cout << a << std::endl;
    return 0;
}

编译时g++ test.cc main.cc返回错误:

/usr/sbin/ld: /tmp/cc6Rs93V.o: in function `main':                                                      
main.cc:(.text+0x41): undefined reference to `ns::operator<<(std::ostream&, ns::test const&)'           
collect2: error: ld returned 1 exit status

显然,编译器将函数解析为ns::operator<<它应该调用的时间operator<<。我知道 C++ 会在参数的命名空间中找到函数,但是我是否错误地实现了运算符重载?像这样的答案似乎和我有相同的实现,唯一的区别是它们都写在标题中。

我做错了哪一部分?我该如何解决这样的问题?

标签: c++namespacesoperator-overloadingheader-files

解决方案


这是我对这种情况的解决方案:

#include<iostream>

namespace ns 
{
    struct test 
    {
        double d;
        test(double x) : d(x) {}
        friend std::ostream& operator<<(std::ostream&, const test&);
    };

    std::ostream& operator<<(std::ostream& os, const ns::test& a) {
        os << a.d;
        return os;
    }
}

int main() 
{
    ns::test a(12);
    std::cout << a << std::endl;
    return 0;
}

推荐阅读