Template parameter list

0

Witam!

Natrafiłem na przykład użycia template parameter list w przykładzie

template <typename... T>
struct outer
{
  template <T... args>
  struct inner {};
};

outer<int, double, char[5]> a;

Nie mam pojęcia jak mogę użyć struktury inner.
Chciałbym zdefiniować zmienną typu outer::inner ale nie ma pojęcia jak to zrobić.
Próbowałem też stworzyć pole w strukturze outer ze zmienną typu inner, ale nie potrafie.

Nie wie ktoś jak to zrobić?

4

A co próbujesz zrobić? inner ma być osobnym szablonem, czy po prostu mieć dostęp do T?

3

W tej chwili ten szablon nie reprezentuje jakąkolwiek funkcjonalności. Ot jakiś szablon, który nikt nie wie po co istnieje.
Niby wiadomo jak można tego, użyć, ale po co?

Czy to jest wciskanie szablonów na siłę do kodu, bo podobno "są fajne" i musisz ich użyć, by udowodnić komuś, że jesteś pro?

0

Nie chce nic robić na siłę, po prostu zobaczyłem taki przykład i okazało się że nie rozumiem jak mogę użyć args w strukutrze inner. Chciałem stworzyć sobie w strukturze outer zmienną o typie inner ale nie umiem. Ja tego nigdzie nie potrzebuje, po prostu jestem ciekawy jak to zrobić. Np.

template <typename... T>
struct outer
{
  template <T... args>
  struct inner {};

  struct inner<"nie wiem co tu wstawić"> x;
  
};
2

Jeśli masz:

outer<int, double, char[5]>

to T0 to typ int, T1 to double i T2 to char[5].

to jest wtedy w zasadzie taki szablon:

  template <int, double, char[5]>
  struct inner {};

Największym problemem przy użyciu tego szablonu jest fakt, że ostatni parametr to char[5]. Nie wiem czy da się stworzyć taką wartość (modyfikowalny string w compile time).

template <typename... T>
struct outer
{
  template <T... args>
  struct inner {};
};

outer<int, double, char[5]>::inner< 520, 123.0, "aaaa" > a;

Coś takiego się nie kompiluje.

<source>:12:49: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]
   12 | outer<int, double, char[5]>::inner< 520, 123.0, "aaaa" > a;
      |                                                 ^
<source>:12:49: error: pointer to subobject of string literal is not allowed in a template argument

Natomiast, gdybyś chciał faktycznie użyć literal stringa w miejscu parametru to da się ale trzeba użyć innego typu.

template <typename... T>
struct outer
{
  template <T... args>
  struct inner {};
};

inline constexpr char s[] = "foob";

outer<int, double, const char(&)[5]>::inner<520, 123.0, s> a;

Możesz też opuścić wielkość arraya:

inline constexpr char s[] = "foob";
outer<int, double, const char(&)[]>::inner<520, 123.0, s> a;

Też się kompiluje.

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0424r2.pdf

2

Możesz zrobić szablon w szablonie:

template <typename... Ts>
struct outer
{
  template <typename... Us>
  struct inner {};
};


int main()
{
    outer<int, double>::inner<std::string, char> a;
}

https://godbolt.org/z/bsaaqhMfT

Albo możesz użyć typów szablonowych wewnątrz wewnętrznej struktury, która szablonem nie jest:

#include <tuple>

template <typename... Ts>
struct outer
{
  struct inner { std::tuple<Ts...> val; };
};


int main()
{
    outer<int, double>::inner a;
    a.val = std::make_tuple(13, 37.0);
}

https://godbolt.org/z/oPqcEn69G

Ciężko powiedzieć co chcesz osiągnąć.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.