Consider the following code with a template method design pattern:
class A {
public:
void templateMethod() {
doSomething();
}
private:
virtual void doSomething() {
std::cout << “42\n”;
}
};
class B : public A {
private:
void doSomething() override {
std::cout << “43\n”;
}
};
int main() {
// case 1
A a; // value semantics
a.templateMethod(); // knows at compile time that A::doSomething() must be called
// case 2
B b; // value semantics
b.templateMethod(); // knows at compile time that B::doSomething() must be called
// case 3
A& a_or_b_ref = runtime_condition() ? a : b; // ref semantics
a_or_b_ref.templateMethod(); // does not know which doSomething() at compile time, a virtual call is needed
return 0;
}
I am wondering if the compiler is able to inline/unvirtualize the “doSomething()” member function in case 1 and 2. This is possible if it creates 3 different pieces of binary code for templateMethod(): one with no inline, and 2 with either A::doSomething() or B::doSomething() inlined (that must be called respectively in cases 3, 1 and 2)
Do you know if this optimization is required by the standard, or else if any compiler implements it ? I know that I can achive the same kind of effect with a CRT pattern and no virtual, but the intent will be less clear.
The optimisation is a problem of the compiler not of the standard. It would be a major bug if an optimisation was leading to a non respect or the princips of virtual functions.
So in the 3rd case :
the actual object is a B, and the actual function called must be the one defined in B class, whatever the reference of pointer used is.
And my compiler displays correctly
43
- has it displayed anything else I would have changed compiler immediately ...