0
#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?

康桓瑋
  • 33,481
  • 5
  • 40
  • 90
Jiehong Jiang
  • 75
  • 1
  • 7
  • Clang prints all `0`s while gcc prints only one `0` and three `1`s. [Demo](https://godbolt.org/z/b1P3rz6Wx) – Jason May 04 '23 at 14:12
  • [Compilers disagree](https://godbolt.org/z/b1P3rz6Wx) – Jason May 04 '23 at 14:12
  • dup of https://stackoverflow.com/questions/68622369/why-is-the-concept-in-template-template-argument-not-verified? – 康桓瑋 May 04 '23 at 14:30
  • @康桓瑋 Yup, here is another [example](https://gcc.godbolt.org/z/d7nT7vhM6) from the dupe where compilers disagree. – Jason May 04 '23 at 14:45
  • Just a follow up to the "compiler disagree" part. I changed the template template argument to argument pack, the compiler behaviors were same now. – Jiehong Jiang May 04 '23 at 15:50

0 Answers0