Template parameter list

Template parameter list
PK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 66
0

Witam!

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

Kopiuj
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ć?

kq
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Szczecin
4

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

MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
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?

PK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 66
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.

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

  struct inner<"nie wiem co tu wstawić"> x;
  
};
mwl4
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 404
2

Jeśli masz:

Kopiuj
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:

Kopiuj
  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).

Kopiuj
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.

Kopiuj
<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.

Kopiuj
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:

Kopiuj
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

kq
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Szczecin
2

Możesz zrobić szablon w szablonie:

Kopiuj
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:

Kopiuj
#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.