0

I know that it is forbidden to call virtual funcs from base ctors, and there are reasons for that. But if the func is "very const", I think, these reasons become irrelevant. "Very const" means the function is straight replacement for a constant, like this:

Color Derived::getColor() const
{
    return Color(0, 255, 0); // no member usage, no member function calls -
                             // only return
}

(I use function because I need its virtuality.) Can I talk the compiler that this func is "very const"? (And it will allow me to call this func from ctor.)

Gordem
  • 115
  • 9
  • [Better not call virtual function from constructor.](https://stackoverflow.com/a/962148/4123703) – Louis Go Aug 17 '20 at 09:00
  • Have you tried with `constexpr Color Derived::getcolor() const`? – Victor Aug 17 '20 at 09:02
  • 2
    Doesn't matter what you do, the vtable hasn't been populated with the derived class methods inside the base class constructors – Alan Birtles Aug 17 '20 at 09:03
  • @Victor Yes, I tried, virtual funcs cannot be `constexpr`, and `consexpr` doesn't forbid the function to read members. – Gordem Aug 17 '20 at 09:05
  • problem is not *what* the method does or how much `const` it is, the problem is *which* method to call in the first place – 463035818_is_not_an_ai Aug 17 '20 at 11:30
  • 2
    From a language perspective, it's not forbidden to call virtual functions from base constructors. It's legal, and its effect is well defined. It's almost always not what you want, so it may be that some coding guidelines forbid it. – Pete Becker Aug 17 '20 at 13:32

2 Answers2

3

If you call a virtual method from a base class constructor you will get the base class method, not any overridden methods.

(Actually, depending on exact circumstances, it may be undefined behaviour, but this is the usual practical effect).

Jasper Kent
  • 3,546
  • 15
  • 21
  • 2
    *"Actually, it's undefined behaviour"* - What? – StoryTeller - Unslander Monica Aug 17 '20 at 09:30
  • @StoryTeller-UnslanderMonica I've clarified. – Jasper Kent Aug 17 '20 at 10:59
  • 1
    Well, to continue, "depending on exact circumstances" -- what circumstances does this refer to? Perhaps pure virtual functions? If so, that's not at issue here, but if you're going to mention it, say it clearly. – Pete Becker Aug 17 '20 at 13:36
  • Whether a mistake in C++ results in predictable or undefined behaviour is not helpful to most programmers, since the bottom line is to avoid the mistake. However, if one doesn't mention the possibility of undefined behaviour, one gets picky complaints. As is the case if one does mention it. – Jasper Kent Aug 17 '20 at 14:21
  • Also, I've no idea how you infer that pure virtual function considerations don't apply here. – Jasper Kent Aug 17 '20 at 14:23
2

Probably not the simplest solution, but CRTP can help in solving such issues...

template <typename Derived>
struct Base {
    Base() {
        c = getColor();
    }

    int getColor() const {
        return static_cast<const Derived&>(*this).getColor();
    }

    int c;
};

struct D1 : Base<D1> {
    int getColor() const {
        return 1;
    }
};

struct D2 : Base<D2> {
    int getColor() const {
        return 2;
    }
};
nop666
  • 585
  • 2
  • 6
  • 1
    In this case you could also make the methods `static constexpr` (aka "very const") Of course, this only works if static polymorphism is possible (unclear from OPs question, IMO ...) – chtz Aug 17 '20 at 10:16