I have an expensive function defined in a base class, which depends on low level information from its derived classes:
class BaseClass{
...
// Defined in derived class
virtual int low_level(int)=0;
// Expensive function depending on the pure virtual function
void myExpensiveFunction(){
for(...){
for(...){
for(...){
... = low_level(...);
...
}
}
}
}
};
class DerivedClass : public BaseClass{
// A very cheap operation that can be inlined:
inline virtual int low_level(int i){
return a[i];
}
// Calling the base class function
void test(){
myExpensiveFunction();
}
};
If I understand things correctly, the fact that the low-level function is virtual prevents it from being inlined in the code above. Now, I was thinking about a way to get around this and thought of the following solution, where I pass a pointer to the derived class member function as a template parameter:
class BaseClass{
...
// The function is now templated by the derived function:
template<typename D, int (D::*low_level)(int)>
void myExpensiveFunction(){
for(...){
for(...){
for(...){
... = static_cast<D*>(this)->low_level(...);
...
}
}
}
}
};
class DerivedClass : public BaseClass{
// A very cheap operation that can be inlined:
inline int low_level(int i){
return a[i];
}
// Calling the base class function
void test(){
myExpensiveFunction<DerivedClass,&DerivedClass::low_level>();
}
};
Does this strategy make sense? I imagine that the low level operation will be inlined when the expensive base class function is expanded in the derived class.
I tested implementing it and it compiles and works, but I haven't seen any noticeable differences in performance.
Kind regards, Joel