Embed a virtual function in a method when an object has semantics of values

Consider the following code with a pattern 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 will be able to embed / disable the member function doSomething () in cases 1 and 2. This is possible if it creates 3 different binary code fragments for templateMethod (): one without inline and 2 with A :: doSomething () or B :: doSomething () inlined (which should be called respectively in cases 3, 1, and 2)

Do you know if this optimization is required by standard, or if any compiler implements it? I know that I can achieve the same effect with a CRT template and without a virtual one, but the intention will be less clear.

+6
source share
2 answers

The standard does not require optimizations at all (sometimes this is done in order to allow them); it determines the result, and it is up to the compiler to figure out how to best achieve it.

In all three cases, I would expect templateMethod be inlined. Then the compiler can perform additional optimizations; in the first two cases, he knows the dynamic type of this and therefore can generate a non-virtual call for doSomething . (Then I expected him to line up these challenges.)

Look at the generated code and see for yourself.

+1
source

Optimization is a non-standard compiler problem. This would be a big mistake if optimization led to disrespect or the principles of virtual functions.

So, in the third case:

 // case 3 A& b_ref = b; // ref semantics b_ref.templateMethod(); 

the actual object is B, and the actual function must be the one defined in class B, regardless of the reference to the pointer used.

And my compiler displays 43 correctly - it displays something else that I would immediately change the compiler ...

0
source

Source: https://habr.com/ru/post/979826/


All Articles