Ivan Gorin
Ivan Gorin

Reputation: 391

std::string comparison not constexpr in clang?

I want a templated function that calls a method of its template class depending on which class it is. I understand that a better way to achieve this would be using std::is_same, but irrelevant for the question.

Here is my minimal example:

#include <iostream>
#include <string>

class A {
public:
    static constexpr std::string name() {return "a";}  
    
    void onlyInA() const {std::cout << "only in a\n";}
};

class B {
public:
    static constexpr std::string name() {return "b";}
};

template <typename C>
void func() {
    C c_{};
    if constexpr (C::name() == "a") {
        c_.onlyInA();
    }
}

int main() {
    func<A>();
    func<B>();
}

Two classes, both have a static constexpr method returning a std::string. In the function, we constexpr compare the std::string and call a method if it's the correct class.

In gcc, this compiles. In clang, it does not (links to godbolt).

The error in clang is not very descriptive:

constexpr if condition is not a constant expression

Ways I've found to fix in clang:

  1. change the return type of name methods to std::string_view: link

  2. put the C::name() into a static constexpr variable, and compare it inside the if: link

But, I still don't understand why the original version does not work in clang (and works in gcc)?. According to cppreference, the comparison operator of std::string is constexpr.

Upvotes: 8

Views: 205

Answers (0)

Related Questions