如何从命名空间内重载运算符<<

How to overload the operator<< from within a namespace

本文关键字:lt 运算符 重载 命名空间      更新时间:2023-10-16

这是我能想到的最小的包含示例。首先是类的标头。每当使用 <<运算符时,此类应简单地打印它包含的一个双精度值。

#pragma once
#ifndef EURO_H
#define EURO_H
#include <ostream>
namespace EU
{
   class Euro final
   {
   public:
        explicit Euro(double value);
        virtual ~Euro() = default;
        double getValue() const;
        friend std::ostream& operator<<(std::ostream &os, const Euro &euro);
    private:
        double m_value;
    };
}
#endif // EURO_H

现在.cpp

#include "euro.h"
using namespace EU;
Euro::Euro(double value)
{
    m_value = value;
}
double Euro::getValue() const
{
    return m_value;
}
std::ostream& operator<<(std::ostream &os, const Euro &euro)
{
    os << euro.getValue() << "EUR";
    return os;
}

最后,主要的.cpp

#include "euro.h"
#include <iostream>
using namespace EU;
int main()
{
    auto e = Euro(3.14);
    std::cout << e << std::endl;
}

但是,当我使用以下方法编译它时:

g++ -std=c++11 *.cpp

它吐出以下错误:

/tmp/ccP7OKC5.o: In function `main':
main.cpp:(.text+0x35): undefined reference to `EU::operator<<(std::ostream&, EU::Euro const&)'
collect2: error: ld returned 1 exit status

我做错了什么?

亲切问候乔里斯

您希望using namespace EU;将所有后续代码放入namespace EU,但它不会(否则您的int main也会在命名空间中!这只会将该命名空间中已有的内容带入范围。

这意味着你在命名空间中声明了 friend 函数,但在全局范围内定义一个新函数。对前者的调用将失败,因为没有定义。

取下using namespacenamespace EU { }包裹在euro.cpp中的所有东西。

从这里更改您的 cpp 文件:

#include "euro.h"
using namespace EU;
Euro::Euro(double value)
{
    m_value = value;
}
double Euro::getValue() const
{
    return m_value;
}
std::ostream& operator<<(std::ostream &os, const Euro &euro)
{
    os << euro.getValue() << "EUR";
    return os;
}

对此:

#include "euro.h"
namespace EU {  
Euro::Euro(double value)
{
    m_value = value;
}
double Euro::getValue() const
{
    return m_value;
}
std::ostream& operator<<(std::ostream &os, const Euro &euro)
{
    os << euro.getValue() << "EUR";
    return os;
}
} // namespace EU

这会将此 cpp 文件中的代码定义为在命名空间中。您之前所做的是声明要在该文件的全局范围内使用的命名空间,因为您没有将源代码定义为在命名空间内。