1

Having a custom type in a namespace and the streaming-operator in a parent namespace, the compiler fails to find the operator in a boost::property_tree::ptree::get() operation. Example:

#include <boost/property_tree/ptree.hpp>

namespace NS1 {
    struct Foo { int foo; };
}

template<typename IStream>
IStream& operator>>(IStream& is, NS1::Foo& val) {
    is >> val.foo;
    return is;
}

namespace NS2 {
    void bar() {
        std::stringstream ss;
        auto& is = static_cast<std::istream&>(ss);
        NS1::Foo foo;
        is >> foo;                         // line 1
    }
}

int main() {
    NS2::bar();                            // line 2

    boost::property_tree::ptree tree;
    tree.get_value_optional<NS1::Foo>();   // line 3
}

In the example, the compiler fails to find the operator unless it is moved into the NS1 namespace. But just the call in line 2 without line 3 does compile! Before line 1 the bar() function even casts the stream to the same type that boost uses in the customize_stream::extract() function that fails the lookup.

My main problem is: what does the call in line 3 do differently from the one in lines 2 that the lookup fails?

And no: I would really prefer not to move the streaming operator into the same namespace as the class.

Olaf Mandel
  • 787
  • 7
  • 20
  • "*I would **really** prefer not to move the streaming operator into the same namespace as the class.*" Then you **really** prefer for your code not to work. – Nicol Bolas Nov 22 '17 at 18:02
  • @Nicol Bolas: Could you please elaborate why moving the operator should be required? That is the main part of the question. – Olaf Mandel Nov 22 '17 at 18:06
  • To clarify my reluctance to extend `NS1`: in my real code, `NS1` is `std`, `Foo` is `tuple` and it is undefined behaviour to add something to `std` (with a few exceptions that apparently don't cover this case). – Olaf Mandel Nov 22 '17 at 18:14

0 Answers0