Thursday, April 28, 2011

Why doesn't this inner class compile?

This is my code:

#include <algorithm>
class A {
  void f() {
    struct CompareMe {
      bool operator() (int i, int j) { return i < j; }
    } comp;
    int a[] = {1, 2, 3, 4};
    int found = std::min_element(a[0], a[3], comp);
  }
}

Error message:

no matching function for call to ‘min_element(int&, int&, A::f()::CompareMe&)

What am I doing wrong?

From stackoverflow
  • The error has nothing to do with your inner class. STL algorithms work on iterators. An iterator into an array of ints is a int*. The second of those iterators must always point to one passed the last element of the range.

    This

    int* found = std::min_element(&a[0], &a[4], comp);
    

    works fine for me.

    However, as far as I remember, C++98 did not allow templates to be instantiated with function-local class types. Unless C++03 fixed that, it's still forbidden. (I think C++11 will allow it, though.) So in order to be fully compliant with the current C++ standard, you would have to move your comparator out of the function into the class. (The class or a file-local unnamed namespace seem good candidates for where to move it to.)

    Marcelo Cantos : This won't pick up the last element.
    sbi : @Marcelo: You are right, I fixed that. Thanks.
  • std::min_element wants iterators as the first two arguments, not values, so std::min_element(&a[0], &a[3], comp) might work

  • Inner classes at function local scope can't be used to instantiate templates. The reason is that those local declarations have no linkage and thus cannot be used by code outside the function.

    You have other options here: declare the functor inside the class, globally or in an unnamed namespace (file static).

    Another issue: min_element returns a forward iterator. You need to dereference it to get the value.

    #include <algorithm>
    
    
    class A {
        struct CompareMe {
          bool operator() (int i, int j) { return i < j; }
        };
      void f() {
    
        int a[] = {1, 2, 3, 4};
        int found = *(std::min_element(a, a + 4, CompareMe() ));
      }
    };
    
    int main() {
    
    }
    

0 comments:

Post a Comment