1

I'm trying to find an object with some attribute value in a custom container that contains an array of objects of another class.

MyIterator<WindowWithTitleButton> WindowList::FindTitle(string title_find)
{   
    auto iter = std::find(this->begin(), this->end(), title_find);
    return iter;
}

"Title" is an attribute of class WindowWithTitleButton and I'm trying to find object in the container with that "title", but I can't figure out how.

I tried to do that with std::find_if

bool WindowList::ContainsTitle(string cmpr, string title)
{
    int result = cmpr.compare(title);
    if (result == 0)
        return true;
    else
        return false;
}
MyIterator<WindowWithTitleButton> WindowList::FindTitle(string title_find)
{   
    MyIterator<WindowWithTitleButton> iter;
    auto i = std::find_if(iter = begin(), iter = end(), ContainsTitle((*iter).GetTitle(),title_find));
    return i;

But it gives me an error C2064 - term does not evaluate to a function taking 1 arguments. How can I properly use this function without error?

1 Answers1

3

In this:

auto i = std::find_if(iter = begin(), iter = end(), 
                      ContainsTitle((*iter).GetTitle(),title_find));

You've made a few mistakes:

  • The iterators should be sent in by value: std::find_if(begin(),end(), ...
  • The UnaryPredicate functor should have the signature bool(const YourWindowsClass&) - that is, it should take one argument and return true or false. The algorithm will loop through all windows in your container and the UnaryPredicate functor will be called with a reference to each element at a time in the container - not an iterator.
  • The UnaryPredicate also needs something to compare with and you can solve that by capturing it in a lambda for example. That's what [&title_find] does in my example below.
MyIterator<WindowWithTitleButton> WindowList::FindTitle(std::string title_find) {
    return std::find_if(begin(), end(),
                        [&title_find](auto&& window) {
                            return title_find == window.GetTitle();
                         });
}

window.GetTitle() is here a member function that returns something that can be compared with a std::string.

If the elements in your container are of type WindowWithTitleButton you can replace auto&& window with const WindowWithTitleButton& window to make it clearer.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • It helped! I was just trying to figure out the ```auto&& window``` and it works fine, but when I input ```const WindowWithTitleButton& window``` instead, I get an error with ```window.GetTitle()```, because WindowWithTitleButton is a derived class from class Window (error: the object has type qualifiers that are not compatible with the member function object type is: const Window) – alex_shevch Jul 06 '22 at 23:01
  • 1
    @alex_shevch I think you've forgotten to make all member functions that doesn't change the element `const` qualified, that's why. Remove `const` and make it `WindowWithTitleButton& window` and it should compile - but I strongly suggest that you go through your member functions to make those `const` that should be :-) – Ted Lyngmo Jul 06 '22 at 23:02
  • 1
    Right, it really was a problem and I missed it. Thank you very much for helping the beginner!) – alex_shevch Jul 06 '22 at 23:10