Reputation: 391
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:
change the return type of name
methods to std::string_view
: link
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