1

std :: find with two different types

 2 years ago
source link: https://www.codesd.com/item/std-find-with-two-different-types.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

std :: find with two different types

advertisements

I am trying to use std::find with two different types but providing the necessary boolean operators.

class FooDetails
{
public:
    FooDetails(int size = 5)
    : m_size(size) { /* empty */ }
    bool operator<(const FooDetails& other) const { return m_size < other.m_size; }
    bool operator==(const FooDetails& other) const { return m_size == other.m_size; }
private:
    int m_size;
};

class Foo
{
public:
    Foo(int size)
    : m_details(size) { /* empty */}

    bool operator==(const Foo& other) const { return m_details == other.m_details; }
    bool operator==(const FooDetails& other) const {return m_details == other; }
    bool operator<(const Foo& other) const { return m_details < other.m_details; }
    bool operator<(const FooDetails& other) const { return m_details < other; }
    FooDetails m_details;
};

bool operator==(const FooDetails& lhs, const Foo& rhs) { return lhs == rhs.m_details; }
bool operator==(const Foo& lhs, const FooDetails& rhs) {return lhs.m_details == rhs; }
bool operator<(const FooDetails& lhs, const Foo& rhs) { return lhs < rhs.m_details; }
bool operator<(const Foo& lhs, const FooDetails& rhs) { return lhs.m_details < rhs; }

int main() {
    std::vector<Foo> haystack = { FooDetails(5), FooDetails(6), FooDetails(7) };

    FooDetails needle(6);
    std::find(haystack.begin(), haystack.end(), needle);
    return 0;
}

Since std::find uses operator== I would expect this to work, since all necessary functions are provided. However this does not compile. Why is that and how do I fix it? I know I could use std::find_if, but I assume that's a bit slower and even if it's not I'd like to know why std::find doesn't work.


I've changed your code to this:

#include <algorithm>

class FooDetails
{
public:
    FooDetails(int size = 5)
    : m_size(size) { /* empty */ }
    bool operator<(const FooDetails& other) const { return m_size < other.m_size; }
    bool operator==(const FooDetails& other) const { return m_size == other.m_size; }
private:
    int m_size;
};

class Foo
{
public:
    Foo(int size)
    : m_details(size) { /* empty */}

    FooDetails m_details;
};

bool operator==(const FooDetails& lhs, const Foo& rhs) { return lhs == rhs.m_details; }
bool operator==(const Foo& lhs, const FooDetails& rhs) {return lhs.m_details == rhs; }
bool operator<(const FooDetails& lhs, const Foo& rhs) { return lhs < rhs.m_details; }
bool operator<(const Foo& lhs, const FooDetails& rhs) { return lhs.m_details < rhs; }

int main() {
    std::vector<Foo> haystack = { Foo(5), Foo(6), Foo(7) };

    FooDetails needle(6);
    std::find(haystack.begin(), haystack.end(), needle);
    return 0;
}

And it successfully compiles. Your original version contains two errors:

  1. You try to create std::vector<Foo> initialising it with std::initialization_list<FooDetails>.
  2. You have provided too many comparison operators: both free versions and members of the Foo struct. So during lookup compiler complains that it doesn't know which one of them to choose. You should leave only one of them.

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK