Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining ostream operator<< for typedef defined in the class

Could anyone provide me a hint how to implement correctly operator<< for MyType in provided code example?

#include <iostream>
#include <map>


template <typename T>
class A {
public:
    typedef std::map<unsigned int, T> MyType;
    MyType data;

    void show();
};

template <typename T>
std::ostream& operator<<(std::ostream& stream, typename A<T>::MyType const& mm)
{
    return stream << mm.size() << "\n";
}

//template <typename T>
//std::ostream& operator<<(std::ostream& stream, std::map<unsigned int, T> const& mm)
//{
//  return stream << mm.size() << "\n";
//}

template <typename T>
void A<T>::show() {std::cout << data;}

int main() {
    A<double> a;

    a.show();

    return 0;
}

Above code does not compile. But when I change definition of operator<< to commented out one, everything works correctly. This is just a (not) working example of a more complicated problem and in reality MyType is much much more nasty. In that simple example I just could easily copy-paste exact definition of MyType from a 'A' class but in more complicated case, when this typedef is depending on antoher typedef... it would be nice just to refer to it. Is there any solution to this problem?

Edit:

Output error from compiler (in general as if operator<< was not defined at all, so when both definitions for operator<< from example are commented out compiler prints same error).

g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++14 -MMD -MP -MF"src/ostreamTest.d" -MT"src/ostreamTest.o" -o "src/ostreamTest.o" "../src/ostreamTest.cpp"
../src/ostreamTest.cpp:27:31: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'MyType' (aka 'map<unsigned int, double>'))
    void A<T>::show() {std::cout << data;}
                       ~~~~~~~~~ ^  ~~~~
like image 789
Krzysztof Avatar asked Oct 23 '25 23:10

Krzysztof


1 Answers

Problem is the non-deduced context (thanks PasserBy for the link), which disallows us to find a direct solution.

A workaround might be moving the typedef out of the class, such as this:

template <typename T>
using A_MyType = std::map<unsigned int, T>;

template <typename T>
class A
{
public:
    typedef A_MyType<T> MyType;
    MyType data;

    void show();
};

template <typename T>
std::ostream& operator<<(std::ostream& stream, A_MyType<T> const& mm)
{
    return stream << mm.size() << std::endl;
}

Sure, this works fine for the std::map, if it works for your more complex class – impossible to say without knowing more details...

like image 111
Aconcagua Avatar answered Oct 25 '25 12:10

Aconcagua



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!