I have a C-struct (in a C header file) that looks like so:
struct Foo {
int a;
int b;
int c;
};
typedef struct Foo Foo;
I want to test equality of two vectors of these structs, and so I would like to define a custom equality operator for this struct for just my translation unit.
I am able to do so with
static inline bool operator==(const Foo&, const Foo&) {...}
but not with
namespace {
bool operator==(const Foo&, const Foo&) {...}
}
Why can the equality template for std::vector not find this operator, and is there a better way than tossing a static inline in the global namespace?
I think you'll find that std::vector
actually does find the operator in the anonymous namespace, if that operator's declaration occurs before #include <vector>
.
The reason it doesn't find it in your code is related to the two-phase lookup for names in template functions. The first phase finds candidates in all namespaces in scope. The second phase only finds dependent names. "Argument-dependent lookup" which searches the namespace containing the type is dependent just as the phrase says. Lookup in the anonymous namespace is not dependent, so it won't be done during the second phase.
See also:
The first thing to be noted is that an anonymous namespace
is not the same as no namespace
.
namespace
{
bool operator==(const Foo&, const Foo&) {...}
}
is really something like
namespace ANameUniqueToTheFile
{
bool operator==(const Foo&, const Foo&) {...}
}
using ANameUniqueToTheFile;
with the downside that the language does not give you the ability to get the name of the namespace
.
For that reason, the operator==
function defined in the anonymous namespace
is not found using ADL.
I can see why you would want to put the operator==
function in a namespace
. One possbile way to do that would be to #include
the .h file that defines the struct
inside a named namespace
.
FooWrapper.h:
namespace MyApp
{
#include "foo.h"
// Declare the function.
bool operator==(Foo const& lhs, Foo const& rhs);
}
FooWrapper.cpp
#include "FooWrapper.h"
namespace MyApp
{
// Implement the function.
bool operator==(Foo const& lhs, Foo const& rhs) { ... }
}
I realize that I'm simplifying a bit about what's in "foo.h". Adding all of them in namesapce MyApp
might not be appropriate, specially if "foo.h" includes other .h files and/or standard header files. I am hoping it gives you some ideas on how to tackle the problem.
If putting all of "foo.h" in namespace MyApp
does not work smoothly, it will probably be expedient to define the operato==
function in global scope.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With