Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I write functors using a private nested struct?

Given this class:

class C
{
    private:
        struct Foo
        {
            int key1, key2, value;
        };
        std::vector<Foo> fooList;
};

The idea here is that fooList can be indexed by either key1 or key2 of the Foo struct. I'm trying to write functors to pass to std::find_if so I can look up items in fooList by each key. But I can't get them to compile because Foo is private within the class (it's not part of C's interface). Is there a way to do this without exposing Foo to the rest of the world?

Here's an example of code that won't compile because Foo is private within my class:

struct MatchKey1 : public std::unary_function<Foo, bool>
{
    int key;
    MatchKey1(int k) : key(k) {}
    bool operator()(const Foo& elem) const
    {
        return key == elem.key1;
    }
};
like image 423
Michael Kristofik Avatar asked Mar 22 '10 15:03

Michael Kristofik


1 Answers

I'd do something like this.

Header:

class C
{
private:
    struct Foo
    {
        int index;
        Bar bar;
    };

    // Predicates used to find Notification instances.
    struct EqualIndex;
    struct EqualBar;

    std::vector<Foo> fooList;
};

Source:

// Predicate for finding a Foo instance by index.
struct C::EqualIndex : std::unary_function<C::Foo, bool>
{
    EqualIndex(int index) : index(index) { }
    bool operator()(const C::Foo& foo) const { return foo.index == index; }
    const int index;
};

// Predicate for finding a Foo instance by Bar.
struct C::EqualBar : std::unary_function<C::Foo, bool>
{
    EqualBar(const Bar& bar) : bar(bar) { }
    bool operator()(const C::Foo& foo) const { return foo.bar == bar; }
    const Bar& bar;
};

Usage:

// Find the element containing the Bar instance someBar.
std::vector<Foo>::iterator it = std::find_if(fooList.begin(),
                                             fooList.end(),
                                             EqualBar(someBar));

if (it != fooList.end())
{
    // Found it.
}

Sort of...

like image 197
Johann Gerell Avatar answered Sep 30 '22 03:09

Johann Gerell