79438359

Date: 2025-02-14 04:18:59
Score: 0.5
Natty:
Report link

In test you try to output foo.bar using printer, which needs an operator<< to output bar. Where printer is defined, there is no output operator for bar, which is defined after' printer. If you forward declare printer and define it after the output operators, everything works.

#include <iostream>
#include <ostream>

namespace ns {
struct Bar {
    int x;
};
struct Foo {
    Bar bar;
};
};  // namespace ns

// Why does this fix things
#if 0
inline std::ostream& operator<<(std::ostream& os, const ns::Bar& bar);
inline std::ostream& operator<<(std::ostream& os, const ns::Foo& foo);
#endif

template <class T>
std::ostream& printer(std::ostream& os, const T& obj);

// I do not own 'ns' but I want to make a generic printer for it
// Wrapping this in 'namespace ns {...}' is the solution, but why?
inline std::ostream& operator<<(std::ostream& os, const ns::Bar& bar) {
    return printer(os, bar);
}

inline std::ostream& operator<<(std::ostream& os, const ns::Foo& foo) {
    return printer(os, foo.bar);
}
template <class T>
std::ostream& printer(std::ostream& os, const T& obj) {
    os << obj;  // error: no match for 'operator<<'
    return os;
}

void test() {
    ns::Foo foo;
    std::cout << foo;
}
Reasons:
  • Blacklisted phrase (0.5): why?
  • RegEx Blacklisted phrase (1): I want
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (0.5):
Posted by: Rud48