hoe de geneste sjablonenparameters afvlakken?

Zeg dat ik het heb

template pack { };

Ik wil converteren

pack>>>

in

pack

Hoe kan ik dat doen?

0
ja ru de
Wilt u ook dingen als pack , int> converteren?
toegevoegd de auteur Holt, de bron

4 antwoord

Ik stel voor de volgende struct en gebruiken

template 
struct flatt_helper
 { using type = T0; };

template 
struct flatt_helper, T0, Ts2...>
   : flatt_helper, Ts2...>
 { };

template  class C, 
          typename ... Ts2, typename ... Ts3>
struct flatt_helper, C, Ts3...>
   : flatt_helper, Ts2..., Ts3...>
 { };

template 
using flatt = typename flatt_helper, T>::type;

This way you can flatten pack and other template-template, as std::tuple, and also more complex examples (the pack, int> suggested by Holt, by example).

Als u alleen flat pack wilt, vermijd dan dat alle sjabloon-sjabloon wordt afgeplat ..., ik bedoel ... als u dat wilt

pack>>

is afgevlakt als

pack>

in plaats van

pack

je moet de template-template parameter verwijderen in de laatste flatt_helper specialisatie en het als volgt vereenvoudigen

template 
struct flatt_helper, pack, Ts3...>
   : flatt_helper, Ts2..., Ts3...>
 { };

Het volgende is een volledig compilatievoorbeeld (met volledige flatting)

#include 
#include 

template 
struct pack
 { };

template 
struct flatt_helper
 { using type = T0; };

template 
struct flatt_helper, T0, Ts2...>
   : flatt_helper, Ts2...>
 { };

template  class C, 
          typename ... Ts2, typename ... Ts3>
struct flatt_helper, C, Ts3...>
   : flatt_helper, Ts2..., Ts3...>
 { };

template 
using flatt = typename flatt_helper, T>::type;

int main()
 {
   using T0 = pack>>>;
   using T1 = pack;
   using T2 = flatt;
   using T3 = pack, std::tuple, long>>;
   using T4 = pack;
   using T5 = flatt;

   static_assert( std::is_same::value, "!" );
   static_assert( std::is_same::value, "!" );
 }
2
toegevoegd
@holt Ik zou het zelfs "verkeerd" noemen.
toegevoegd de auteur Yakk - Adam Nevraumont, de bron
@Holt - ja, was niet duidelijk; antwoord gewijzigd; de hoop is nu duidelijker
toegevoegd de auteur max66, de bron
Leuk antwoord met het opbouwen van pack <> maar je moet erop wijzen dat, met de template template parameter, dit alles plat maakt, zoals flatt < int >>> is eigenlijk pack , wat hier niet het verwachte gedrag is.
toegevoegd de auteur Holt, de bron

ik zou dingen recursief uitpakken en opnieuw inpakken:

template
struct repack
{
    using type = Head;
};

template
struct repack>>
{
    using type = pack
>; }; 

The type repack>>>>::type get transformed into:

  • pack>>>>
  • pack>>>
  • pack>>
  • pack

Live demo

1
toegevoegd
Deze code genereert niet het type waarvan u denkt dat het het doet. Noch behandelt het `pack right.
toegevoegd de auteur Yakk - Adam Nevraumont, de bron

Een mogelijke snelle implementatie op basis van std :: tuple_cat :

template 
struct tuple_flatten {
    using type = std::tuple;
};

template 
struct tuple_flatten> {
    using type = decltype(std::tuple_cat(
        typename tuple_flatten::type{}...));
};

template 
struct tuple_to_pack;

template 
struct tuple_to_pack> {
    using type = pack;
};

template 
struct flatten {
    using type = typename tuple_to_pack<
        typename tuple_flatten::type>::type;
};

template 
using flatten_t = typename flatten::type;

Godbolt demo

1
toegevoegd

pack_cat takes a sequence of packs or non-packs, and concatinates anything that is a pack together, plus items that are not packs.

template
struct catter;
template
using pack_cat = typename catter::type;
template
struct catter{ using type=T0; };
template
struct catter, pack, Vs...>{ using type=pack_cat,Vs...>; };
template
struct catter, U, Vs...>{ using type=pack_cat,Vs...>; };

unpacker takes a pack, and recursively unpacks all sub-packs and concatinates them.

template
struct unpacker{using type=X;};
template
using unpack=typename unpacker::type;
template
struct unpacker>{using type=pack_cat,unpack...>;};

Om het te testen:

pack{}=unpack>>>>{};
pack{} = unpack>{};
pack{} = unpack,int>>{};

die IFF compileren, de twee typen zijn hetzelfde.

0
toegevoegd