I’ve the following code
#include <cstdint>
#include <concepts>
template <class T>
concept has_id = requires(T) {
T::Id;
std::same_as<uint8_t[16], decltype(T::Id)>;
};
The has_id concepts ensure that a type has the member Id with type uint8_t[16].
However, when writing the following example it works even though the Id has type uint8_t[17] which is invalid.
#include <cstdint>
#include <iostream>
class Sample
{
public:
static constexpr uint8_t Id[17] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11};
};
template<has_id T>
void print_id()
{
std::cout.setf(std::ios_base::hex);
std::cout << "{" << (int)T::Id[0];
for(auto i=1; i < sizeof(T::Id); ++i)
std::cout << ", " << (int)T::Id[i];
std::cout << "}";
}
int main()
{
print_id<Sample>();
return 0;
}
I’ve tried it on Visual C++ 2022 17.3 and Clang 14 and they give the same result, any idea why?
>Solution :
template <class T>
concept has_id = requires(T) {
T::Id;
std::same_as<uint8_t[16], decltype(T::Id)>;
};
Confirms that the expression T::Id compiles, and that the expression std::same_as<....> compiles. It doesn’t check whether the latter is true or false.
You can just write
template <class T>
concept has_id = requires(T) {
T::Id;
requires std::same_as<uint8_t[16], decltype(T::Id)>;
};
to change the constraint from must compile to must be true.
Note GCC 12 helpfully emits the following warning with your original code:
<source>:7:2: warning: testing if a concept-id is a valid expression;
add 'requires' to check satisfaction [-Wmissing-requires]