1

So I've used C for a long time and Java, too, but I'm not that familiar with C++. The situation is that we have:

base class template 1 -> base class template 2 -> several relevant subclasses

Currently all of the final subclasses inherit a member function from class 1, but we need to change the behavior of this function only in one of the subclasses, and only if a variable elsewhere in the code is set, and otherwise run the function as defined in class 1. Is there a way to do this without slotting the entire function definition on the other side of an if-else? I've looked at SFINAE/enable-if, but that's used for type-based decisions, not simple conditionals like this.

If I'm missing anything easy or dumb please let me know.

Some pseudocode might help:

template <class Face> class Publisher {
  virtual void publish(...) {
    // do stuff
  }
}

template <class NewsType> class NewsPublisher : public Publisher<OnlineFace> {
  // constructors, destructors...
}

class MagazinePublisher : public NewsPublisher<Sports> {
  void publish(...) {
    if(that.theOther() == value) {
      // do different stuff
    } else {
      // do whatever would have been done without this override here
    }
  }
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Bronze
  • 153
  • 1
  • 8
  • 2
    Could you at least give us a minimal pseudo code sample, it's very hard to get the actual situation from your prose. – πάντα ῥεῖ Jul 06 '16 at 16:19
  • 2
    Have you tried `if (condition) return base_class::foo(args); else /* doing something else */`? – W.F. Jul 06 '16 at 16:21
  • @W.F. If I understand correctly the OP states in the question they do not want to use `if-else` logic to do this. – James Adkison Jul 06 '16 at 16:22
  • @JamesAdkison as I understand OP correctly he does not want to `slotting the entire function definition` in the child function... – W.F. Jul 06 '16 at 16:25
  • @W.F. Okay, well I guess I just don't understand the question because I don't know what "slotting" means. If it's a synonym for duplicating the base implementation then I agree with your original comment about explicitly calling the base implementation. – James Adkison Jul 06 '16 at 16:29
  • What I mean here is that I just don't want to copy-paste the base class's function definition into an if-else. It's a big function and I don't want to needlessly muck up the code if I can avoid it. – Bronze Jul 06 '16 at 16:31
  • 1
    @Bronze you realize you can [call base class functions](http://stackoverflow.com/a/357380/4892076) in C++? That's what W.F. is doing in the above comment, and it would prevent the copy/paste – jaggedSpire Jul 06 '16 at 16:32
  • @jaggedSpire Having tried just this I was rebuked by the compiler because the function cannot be called without the object: – Bronze Jul 06 '16 at 16:34
  • The NewsPublisher class has some important attributes that get instantiated and inherited by MagazinePublisher, so I can't just call Publisher::publish(). – Bronze Jul 06 '16 at 16:40
  • 1
    @Bronze perhaps you need [a working example?](http://coliru.stacked-crooked.com/a/0e7f84e1c8b7e7e7) If the attributes are virtual, it'll simply get that information from MagazinePublisher – jaggedSpire Jul 06 '16 at 16:40
  • 1
    @jaggedSpire Funny, I was just [doing the same thing](http://ideone.com/10VG5g). – James Adkison Jul 06 '16 at 16:42

1 Answers1

4

According to your example you can simply call the base class implementation explicitly:

class MagazinePublisher : public NewsPublisher<Sports> {
  void publish(...) {
    if(that.theOther() == value) {
      // do different stuff
    } else {
      // call the base class implementation, as this function would not
      // have been overridden:
      NewsPublisher<Sports>::publish(...);
   // ^^^^^^^^^^^^^^^^^^^^^^^
    }
  }
}

Well, I suppose your actual base class function publish() is declared as virtual member.


Also since your sample is just pseudo code and I couldn't really test it, you might need to add which publish() implementation should be used in the NewsPublisher<T> class:

template <class NewsType> class NewsPublisher : public Publisher<OnlineFace> {
public:
  // constructors, destructors...
  using Publisher<OnlineFace>::publish(); // <<<<<<<<<<<<<
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • Yeah, this is what I'm going with. The last bit with the full name scope was what I was struggling with. Thank you very much! – Bronze Jul 06 '16 at 16:58