If compiled with gcc v10 the code below exibits an error but for gcc v9 the code is ok.
template<auto N>
struct A {
constexpr auto size() const {
return N;
}
};
template<typename T>
void foo1(const T& a) {
constexpr auto s = a.size(); // Why error here?
}
template<typename T>
void foo2(T a) {
constexpr auto s = a.size(); // OK
}
int main() {
A<10> x1;
foo1(x1);
foo2(x1);
A<x1.size()> x2; // OK
constexpr auto s = x1.size(); // OK
}
In my understanding the memberfunction size() could be called constexpr in all cases. But there is one case where the behaviour of gcc10 changed compared to gcc9: if the argument is passed by const-ref. I don't understand why this should not be constexpr?
Another example:
template<auto N>
struct A {
constexpr auto size() const {
return N;
}
};
template<typename T>
constexpr void foo1(const T& a) {
constexpr auto s = a.size(); // Why error here?
return s;
}
template<typename T>
constexpr auto foo2(const T& a) {
return a.size(); // Why OK here
}
int main() {
A<10> x1;
constexpr auto s1 = foo1(x1);
constexpr auto s2 = foo2(x1);
}
I don't understand the difference.
This is GCC bug 66477. It mentions that GCC wrongly accepts reference-type parameters in constant expressions.
This bug is fixed for GCC 10.
The reason why a.size()
is not allowed in constant expressions is mentioned in this post.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With