Search code examples
c++templates

Why isn't this evaluated as constant expression?


I really expected this to work:

#include <type_traits>

struct serialiser_deserialiser
{
    template <typename U>
    void read_or_write(U& obj_to_write)
    {
        if constexpr (this->isTrue<int>())
        {
        }
    }

    template <typename T>
    constexpr bool isTrue() const { return true; }
};

int main() {
    serialiser_deserialiser serialiser_obj;
    int a;
    serialiser_obj.read_or_write(a);
}

However the error I get is:

error: constexpr if condition is not a constant expression

What is the reason this isn't a constant expression? Does it have something to do with the fact that it's isTrue() is being called from a templated function? Or that isTrue itself is a templated function?


Solution

  • As to explain why your code is wrong
    constexpr is meant to eliminate all side effects and to have the calculation doable at compilation time (even though it can also be called during runtime).
    As soon as you dereference the non-constexpr this pointer you depend on a runtime instance, no matter what the method will do.

    As @Jarod42 pointed out in the comments:
    When you make isTrue as a static constexpr method, then you don't need the this pointer and the expression has no more side effects.
    Use

    if constexpr (isTrue<int>())
    

    or more explicitly

    if constexpr (struct serialiser_deserialiser::isTrue<int>())