admin管理员组

文章数量:1289382

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?

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?

Share Improve this question edited Feb 20 at 0:26 3CxEZiVlQ 38.9k11 gold badges79 silver badges91 bronze badges asked Feb 20 at 0:21 ZebrafishZebrafish 14.4k3 gold badges64 silver badges152 bronze badges 9
  • 1 serialiser_obj is not a constexpr object – NathanOliver Commented Feb 20 at 0:24
  • 4 gcc 14.2 gives a much more useful diagnostic: error: 'this' is not a constant expression – user4581301 Commented Feb 20 at 0:27
  • 2 In defense of clang, versions 10 and better spit out a supplementary message: note: use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function – user4581301 Commented Feb 20 at 0:32
  • 1 I would rather ask you: what's the idea behind if constexpr (this->isTrue<int>())? :-) What did you try to achive? – Sergey A Kryukov Commented Feb 20 at 0:35
  • 1 @SergeyAKryukov It was the most basic test I could think of to try to find the cause of my error message. It's to branch, if it has a function call the function, otherwise do something else. – Zebrafish Commented Feb 20 at 1:21
 |  Show 4 more comments

1 Answer 1

Reset to default 3

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>())

本文标签: cWhy isn39t this evaluated as constant expressionStack Overflow