Search code examples
c++optimizationc++17compile-timeif-constexpr

Is there an effective way to assert an constexpr-if branch is executed?


int f(auto obj) {
    if constexpr (HasFastGetData<decltype(obj)>) {
        return obj.FastGetData();
    } else {
        return obj.GetData();
    }
}

int main() {
    B obj;
    f(obj);
    // How to verify obj.FastGetData(), rather than obj.GetData(), is executed?
}

Take the code above as an example:

  • I have two classes A & B.
  • A has a member function int GetData() and B has a member function int FastGetData().
  • The two functions have the same symantics, but FastGetData is faster than GetData.
  • I want f to differentiate the types of obj for better performance.

I just wonder:

Is there an effective way to unit test my intent?


Solution

  • You can either add static_assert(HasFastGetData<B>) after the call to f or return a std::pair containing the result:

    Method 1

    f(obj);
    //------------vvvvvvvvvvvvvvvvv--->condition of first branch goes here
    static_assert(HasFastGetData<B>); //this makes sure that the first branch if taken 
    
    

    Method 2

    You can also return a std::pair(or a custom struct with sensible named members) to check:

    std::pair<int,int> f(auto obj) {
        if constexpr (HasFastGetData<decltype(obj)>) {
            return {1, obj.FastGetData()};
        } else {
            return {0,obj.GetData()};
        }
    }
    int main() {
        B obj;
        std::pair<int, int> result = f(obj);
        if(result.first){} //first branch taken
        else{} 
        
    }