'std::find does not find free operator==

I have the following structs definied in my Project:

// Condition.h
struct Condition {
    std::string key{};
    std::string value{};
}
//Metadata.h
struct Metadata {
   std::string key{};
   std::string value{};
   std::string other{};
}

Then i have defined a check Function in another .h/.cpp files like this:

// Checker.h
namespace util {
    bool operator==(const Metadata& metadata_element, const Condition& condition);
    bool operator!=(const Metadata& metadata_element, const Condition& condition);
    bool operator==(const Condition& condition, const Metadata& metadata_element);
    bool operator!=(const Condition& condition, const Metadata& metadata_element);
    bool check(const Condition& condition, const std::vector<Metadata>& metadata);
}
//Checker.cpp 
namespace util {
    bool operator==(const Metadata& metadata_element, const Condition& condition) {
      return metadata_element.key == condition.condition && metadata_element.value == condition.value;
    }

    bool operator!=(const Metadata& metadata_element, const Condition& condition) {
      return !(metadata_element == condition);
    }

    bool operator==(const Condition& condition, const Metadata& metadata_element) {
      return metadata_element == condition;
    }

    bool operator!=(const Condition& condition, const Metadata& metadata_element) {
      return !(condition == metadata_element);
    }

    bool check(const Condition& condition, const std::vector<Metadata>& metadata) {
      return std::find(metadata.begin(), metadata.end(), condition) != metadata.end(); // gives me an error
    }
}

Doing something like condition == metadata[0] works. But if i add the std::find call i got the following error:

error C2676: binary '==' : 'const Metadata' does not define this operator or a conversion to a type acceptable to the predefined operator

I also tried to copy the code to some new project and there it works without any trouble which i found a little bit strange.

EDIT:

The Problem seems to be because the Operators are in an different Namespace then the two Structs.



Solution 1:[1]

The usual practice is to declare the operators (==, !=, etc.) in the same header as the types they operate on, as the operators are part of the interface:

// condition.h
struct Condition {
    // (...)
}

bool operator==(const Condition & lhs, const Condition& rhs) {
    // (...)
}

If you have good reasons to place those declarations in separate headers, just make sure that each source file that uses the operators (like the place where you call std::find) includes also the header with operators:

// condition.h
struct Condition {
    // (...)
}
// condition_eq.h
#include "condition.h"

bool operator==(const Condition & lhs, const Condition& rhs) {
    // (...)
}
// find.cpp
#include "condition.h"
#include "condition_eq.h"

// some code that uses the operator ==

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Krzysiek Karbowiak