There is no reason why code should get complicated when using templates:
template<bool enable_optimization> class FooOptimized { protected: int b; void bar_optim() { b = 0; } }; template<> class FooOptimized<false> { protected: void bar_optim() { } }; template<bool enable_optimization> struct Algo { struct Foo : FooOptimized<enable_optimization> { int a; void bar() { this->bar_optim(); } }; };
There is no need for metaprogramming, just separate the parts that change depending on whether optimization is included in the new type and specializes in it.
Since the new type is used as the base class when it is empty (i.e. there is no FooOptimized::b member), it will not take a space, therefore sizeof(Algo<false>::Foo) == sizeof(int) .
(Feel free to ignore the rest of this answer, it does not address the issue directly, instead it offers a different approach that has different trade-offs. Whether it is βbetterβ or not, the actual code that is not shown in a trivial example depends entirely on the details. asked in the question.)
As a related but separate issue, parts of Algo and Algo::Foo that do not depend on whether optimization is turned on still depend on the template parameter, therefore, although you only write these bits of code once, the compiler will generate two sets of object codes. Depending on how much work is in this code and how it is used, you may find that there is an advantage to changing this to code without a template, i.e. replacing static polymorphism with dynamic polymorphism. For example, you can make the enable_optimization flag enable_optimization argument to the runtime constructor instead of a template argument:
struct FooImpl { virtual void bar() { } }; class FooOptimized : FooImpl { int b; void bar() { b = 0; } }; struct Algo { class Foo { std::unique_ptr<FooImpl> impl; public: explicit Foo(bool optimize) : impl(optimize ? new FooOptimized : new FooImpl) { } int a; void bar() { impl->bar(); } }; };
You will need to profile and test it to determine if a virtual function has less cost than duplicating code in Algo and Algo::Foo , which is independent of the template parameter.
Jonathan wakely
source share