#include <iostream>
#include <vector>
struct UUID{};
struct IHaveUUID
{
UUID GetUUID() { return uuid; }
void SetUUID(UUID uuid){ this->uuid = uuid; }
UUID uuid;
};
struct IDontHaveUUID
{};
template <class T>
concept HasUUID = requires(T a, UUID uuid) {
a.GetUUID();
a.SetUUID(uuid);
};
// version 0
template<class T>
struct HasUUIDContained_V0 : std::false_type {};
template<template <class U> class T, class U> requires HasUUID<U>
struct HasUUIDContained_V0<T<U>> : std::true_type {};
// version 1
template<class T>
struct HasUUIDContained_V1 : std::false_type {};
template<template <class U> requires HasUUID<U> class T, class U>
struct HasUUIDContained_V1<T<U>> : std::true_type {};
int main()
{
cout<< HasUUIDContained_V0<std::vector<IHaveUUID>>::value << std::endl; // output 1
cout<< HasUUIDContained_V0<std::vector<IDontHaveUUID>>::value << std::endl; // output 0
cout<< HasUUIDContained_V1<std::vector<IHaveUUID>>::value << std::endl; // output 1
cout<< HasUUIDContained_V1<std::vector<IDontHaveUUID>>::value << std::endl; // output 1, what??? I expect 0 too
return 0;
}
// executed in onlinegdb with C++20
I want to write a type trait that checks if a the inner type of a container type is a class that has UUID interface. The version 0 does work as I expected, but version 1 doesn't. Even though version 1 compiles it doesn't check the required concept. What happened here? Where does the template template class' concept apply to?