2

I need to have a template struct Lists, whose variadic parameters can only be the types represented by specializations of some certain container template List. Different Lists instances should be able to depend on different (but fixed for one instance) templates List.

That said, I want to produce the code, equivalent to following pseudocode:

template<typename...>
struct Lists;

// pseudocode. Is there a way to do something similar?
template<template<typename...> typename List, typename... Types>
struct Lists<List<Types...>...>{};

int main()
{
    Lists<std::pair<int, char>,std::pair<double, char>> lists;
    Lists<std::tuple<int, char>,std::tuple<double, char>> lists;
    //Lists<std::pair<int, char>,std::tuple<double, char>> lists;   // must cause a compilation error
    return 0;
}

How can I do that in modern C++?

soad
  • 49
  • 6

1 Answers1

1
template <template <typename...> typename, typename>
inline constexpr bool is_specialization_of = false;

template <template <typename...> typename Template, typename... Ts>
inline constexpr bool is_specialization_of<Template, Template<Ts...>> = true;

template <typename...>
struct Lists;

template <template <typename...> typename Template, typename... Ts,
          typename... Others>
    requires(is_specialization_of<Template, Others> && ...)
struct Lists<Template<Ts...>, Others...> {};

int main() {
    Lists<std::pair<int, char>, std::pair<double, char>> lists0;        // OK
    Lists<std::tuple<int, char>, std::tuple<double, char>> lists1;      // OK
    /* Lists<std::pair<int, char>,std::tuple<double, char>> lists2; */  // ERROR
}

live example on godbolt.org

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • awesome, thank you. a couple questions about your solution: 1. Do I really need to implement `is_specialization_of` by myself? This seems like smth that might have already been defined in standard library. 2. `requires(is_specialization_of – soad Oct 13 '22 at 21:35
  • 1
    1. It was proposed, but never accepted AFAIK. 2. That line is using concepts (C++23, `requires` keyword), and fold expressions (C++17) -- you can look into those two things. – Vittorio Romeo Oct 13 '22 at 21:37