2

I'm using a C struct (that I do not control) and wrote a freestanding operator== implementation for it in a namespace. I have another class that has that C struct as a member and that also has an operator== implementation. Originally I had:

#include <tuple>

struct Foo
{
    int x;
};

struct Bar
{
    Foo foo;
    int y;
};

namespace foo_ops
{
    bool operator==(const Foo& f1, const Foo& f2)
    {
        return f1.x == f2.x;
    }
}

bool operator==(const Bar& b1, const Bar& b2)
{
    using namespace foo_ops;
    return b1.foo == b2.foo && b1.y == b2.y;
}

which works. I'd like to change the operator==(const Bar&, const Bar&) to use std::tuple instead:

bool operator==(const Bar& b1, const Bar& b2)
{
    using namespace foo_ops;
 
    auto asTuple = [](const Bar& b)
    {
        return std::tie(b.foo, b.y);
    };

    return asTuple(b1) == asTuple(b2);
}

but that fails to resolve because the compiler won't choose foo_ops::operator== when comparing the Foo members. Argument-dependent lookup doesn't help here since the Foo struct is declared in a different namespace from the corresponding operator==.

It apparently does work if I add a using foo_ops::operator==; declaration in the global scope. That declaration does not help if used in the function's scope. A globally-scoped using namespace foo_ops; directive also does not help.

My questions:

  • Is there any way to get std::tuple::operator== to choose foo_ops::operator== without a globally-scoped using declaration? (Or perhaps I should give up on having operator==(const Foo&, const Foo&) live in a separate namespace and move it to the global one?) I suspect that the answer is no, and using foo_ops::operator==; isn't too bad, but maybe I'm missing some alternative.

  • Not that I'd really want to use a globally-scoped using namespace foo_ops; directive, but why does that fail when using foo_ops::operator==; succeeds?

jamesdlin
  • 81,374
  • 13
  • 159
  • 204

0 Answers0