How to present a variational template type based on another group of variational template arguments in modern C ++?

Suppose I have the following variational pattern structure:

template <class... T> 
struct Example {};

Now I want to define a template function:

template<class... S>
??? f() {
    return Example<???>
}

where specialization Example<>depends on the template parameter Sfrom f.

To be more specific (and simple), now I just want to return Example<int, ...,int>where the number intis the size of the parameter packet S.

How can this be done in modern C ++, i.e. C ++ 11/14/17?

In general, is there a way at compile time to determine a function by template parameters?

+3
source share
2 answers

IMO "-" " -" . , "-", , . , , ( " ": ) ( " ": ).

, , .. S. S . , , , , . mapping. , , .. mapping . map.

:

// mapping :: TYPE -> TYPE
// ---------------------------------------------------------
// ?? --> int (default "value")
template<typename X> struct mapping {
  using type = int;
};
// if instead you want it to be undefined for unknown types:
//template<typename X> struct mapping;
// bool --> double
template<> struct mapping<bool> {
  using type = double;
};

map, , - mapping:

// map :: ([T] -> T) -> (T -> T) -> ([T] -> T)
//         "List"       "Mapping"   result "type" (also a "List")
// --------------------------------------------------------
template<template<typename...> class List,
         template<typename> class Mapping>
struct map {
  template<typename... Elements>
  using type = List<typename Mapping<Elements>::type...>;
};

, Example ( , "" ) mapping:

template<typename... S>
using MappedExample = map<Example, mapping>::type<S...>;

, -:

template<typename... S>
MappedExample<S...> f() {
  return MappedExample<S...>{};
}

:

int main() {
  std::cout
    << typeid(Example<bool,int,char,double>).name()
    << std::endl
    << typeid(decltype(f<bool, int, char, double>())).name()
    << std::endl;
}

:

7ExampleIJbicdEE Example b ool, i nt, c har, d ouble.
7ExampleIJdiiiEE Example d ( bool) 3 i nt ( ).

0

:

// Maps some type T to the type U.
template <typename T, typename U>
using Map = U;

:

template<class... S>
Example<Map<S, int>...> f() {
    return Example<Map<S, int>...>{};
}
+4

Source: https://habr.com/ru/post/1016401/


All Articles