How to overload the operator<< from within a namespace

扶醉桌前 提交于 2019-12-23 16:48:27

问题


This is the smallest contained example I can think of. First the header of the class. This class should simply print the one double it contains whenever the << operator is used.

#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

Now the .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;
}

And finally, the main.cpp

#include "euro.h"

#include <iostream>

using namespace EU;

int main()
{
    auto e = Euro(3.14);
    std::cout << e << std::endl;
}

However, when I compile this using:

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

it spits out the following error:

/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

What am I doing wrong?

Kind regards, Joris


回答1:


You're expecting using namespace EU; to put all the subsequent code inside namespace EU, but it won't (otherwise your int main would be in the namespace too!). This just brings things already in that namespace into scope.

It means that you're declaring the friend function inside the namespace, but defining a new function in the global scope. Calls to the former will fail because there's no definition for it.

Remove the using namespace, and wrap namespace EU { } around everything in euro.cpp.




回答2:


Change your cpp file from this:

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

to this:

#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

This defines the code within this cpp file to be within the namespace. What you was previously doing was declaring your namespace to be used at the global scope of that file as you were not defining your source code to be within the namespace.



来源:https://stackoverflow.com/questions/36776051/how-to-overload-the-operator-from-within-a-namespace

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!