I found when I using a concept with requires expression, the compiler won’t match the constraints but report an ambiguous error. After replace the requires expression to a common expression, it actually passed the compile. What is the difference between adding a requires expression to a concept and not adding one ?
Here is the demo code:
#include <cstdint>
class uint63;
template<typename T>
/*
// this got error
concept is_not_uint63_t = requires {
!std::same_as<T, uint63>;
};
*/
// and this pass the compile
concept is_not_uint63_t = !std::same_as<T, uint63>;
class uint63 {
template<is_not_uint63_t T>
friend uint63 operator +(T t, uint63 u) {
return u.container_ + static_cast<uint64_t>(t);
}
private:
uint64_t container_;
public:
uint63(uint64_t u) : container_(u) {}
operator uint64_t () {
return this->container_;
}
template<typename T> uint63 operator +(T n) const { return { this->container_ + static_cast<uint64_t>(n) }; }
};
int main() {
uint63 k = 1;
uint63 w = k + 1;
uint63 r = k + w;
}