0

I want to have some overloaded functions in the derived class, but it does not work. What is the reason? and how to make it work?

#include <stdio.h>
struct A {};

struct Compare {
  template <typename T> bool operator()(const T& a, const T& b) const {
    printf("from operator()\n");
    return compare(a, b);
  }
  private:
  template <typename T> bool compare(const T& a, const T& b) const {
    printf("from base compare template \n");
    return true; 
  }

  // move into derived class, but does not work
  // bool compare(const A& n, const A& p) const {
  //  printf("from base overload\n");
  //  return true;
  // }
};

struct CompareDerived : public Compare {
  bool compare(const A& n, const A& p) const {
    printf("from derived overload\n");
    return true;
  }
};

template <typename T, typename Comp = Compare> bool trigger (const T& a, const T&b, const Comp& compare = Comp()) {
    return compare(a, b);
}

int main()
{
    A a1, a2;
    CompareDerived m;
    trigger<A, CompareDerived>(a1, a2, m);
    return 0;
}

by https://godbolt.org/z/hTGjjx43o, print result:

from operator()
from base compare template 
pepero
  • 7,095
  • 7
  • 41
  • 72
  • compare is template function, so it is anyhow not virtual – pepero Nov 17 '21 at 15:46
  • Copy `operator()` into `CompareDerived`. Or call `compare.compare(a, b)` – KamilCuk Nov 17 '21 at 15:48
  • why should I copy that, shouldn't the CompareDerived already has it? – pepero Nov 17 '21 at 15:49
  • It has - it has `Compare::operator()` and that calls `Compare:;compare`. It has no `operator()` that would call `CompareDerived::compare`. The call inside `Compare::operator()` is static, resolved at compile time, will always point to `Compare::compare`. – KamilCuk Nov 17 '21 at 15:50
  • but the Compare::compare will choose to call between the overloaded compare and template compare, no? I expect the CompareDerived would be the same as the Compare class with overloaded function uncommented, no? – pepero Nov 17 '21 at 15:55
  • @KamilCuk, you are right, if I copy the operator() into CompareDerived, it works. could you elaborate what happens? Sorry, I did not really get it. – pepero Nov 17 '21 at 16:00
  • @KamilCuk, then the inheritance here is not useful at all... – pepero Nov 17 '21 at 16:16
  • You might be looking for CRTP. As in `template struct Compare {...};` then in `operator()` you do `return static_cast(this)->compare(a, b)`, and finally `struct CompareDerived : public Compare {...};` [Demo](https://godbolt.org/z/z3bT5YqKf) – Igor Tandetnik Nov 17 '21 at 16:21

0 Answers0