I am trying to use an int member of a constexpr object as a template parameter. The idea is that I create a constexpr Symbol and then have that converted into a SymbolRef<1> (in the real code that 1 is different for different objects).
template<int Id>
struct SymbolRef { };
struct Symbol {
int const id_;
consteval Symbol() : id_(1) { }
template<int Id>
consteval operator SymbolRef<Id>() const
{
return SymbolRef<id_>{};
}
};
However, trying to compile the above code I get the error:
error: non-type template argument is not a constant expression
12 | return SymbolRef<id_>{};
| ^~~
<source>:12:22: note: implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function
The phrase "is only allowed within the evaluation of a call to a 'constexpr' member function" seems to not apply: this is a consteval function!?
I understand that this code is ill-formed when operator SymbolRef<Id>() would be a constexpr member function (in spite of the error message!) because in that case the function must also compile without the constexpr, in which case this->id_ can't be used as a template parameter.
Why is this code illegal when using it with consteval?
EDIT:
The following does compile with g++ - but only when using this->id_.
template<int Id>
struct SymbolRef { };
struct Symbol {
int const id_;
consteval Symbol() : id_(1) { }
template<int Id>
consteval operator SymbolRef<Id>() const
{
return SymbolRef<this->id_>{};
}
};
I am guessing it is a compiler bug therefore? It seems that the correct behavior is that it would compile with or without this-> and clang++ is just wrong.
constevalfonction/class.thisis just a function parameter)