1
votes

Utilisation répétée d'un paramètre de modèle non type dans la portée de bloc

J'ai l'extrait de code suivant:

template <size_t N>
foo make() { ... }

...

for (...) {
    auto foo = make<1>();
    // lots of tests involving foo
}

Je voudrais répéter ce dernier bloc avec des valeurs différentes pour le paramètre de modèle non-type à make , par exemple, make , make , etc.

Si c'était un type que je voulais parcourir, je pourrais utiliser cette solution , mais il n'est pas clair que je puisse utiliser des paramètres de modèle non-type avec un lambda générique de la même manière.

Comment puis-je prendre en compte cela pour que je puisse créer exécuter le bloc de code ci-dessus mais instancier make avec des valeurs différentes pour son paramètre non-type. La solution ne doit utiliser que des éléments à portée de bloc - c'est facile si je peux créer un objet template struct maker {...} de niveau supérieur pour envelopper make code >.


2 commentaires

Alors, avez-vous un index de terminaison? Et êtes-vous sûr de vouloir commencer à 1 plutôt qu'à 0?


@NicolBolas - dans ce cas, je veux commencer à 1, mais si une solution avec 0 est beaucoup plus propre, je peux m'y adapter. L'index de terminaison est ~ 10, mais je suis également d'accord pour lister les cas à la main, comme quelque chose {bar <1>, bar <2>, ...} ou autre (mais pas dupliquer tout le code dans la boucle for ).


3 Réponses :


1
votes

Comme point de départ avec la liste d'index fabriqués à la main:

    template < size_t FIRST, size_t LAST >
void ExecuteAndTest_Impl()
{   
    auto foo = make<FIRST>();
    std::cout << "Here we go with the test" << foo << std::endl;

    // go for next step
    if constexpr ( LAST!= FIRST) { ExecuteAndTest_Impl<FIRST+1, LAST>(); }
}

    template < size_t LAST > 
void ExecuteAndTest()
{   
    ExecuteAndTest_Impl<1,LAST>();
}   

int main()
{   
    // or always start with 1 to n inclusive
    ExecuteAndTest<3>();
}  

ou vous pouvez simplement le rendre récursif et utiliser l'index en premier et en dernier comme ceci:

template < size_t FIRST, size_t LAST >
void ExecuteAndTest()
{
    auto foo = make<FIRST>();
    std::cout << "Here we go with the test" << foo << std::endl;

    // go for next step
    if constexpr ( LAST != FIRST ) { ExecuteAndTest<FIRST+1, LAST>(); }
}

int main()
{
    // first and last index of integer sequence
    ExecuteAndTest<1,3>();
}


0 commentaires


0
votes

Vous pouvez essayer ceci:

#include <utility>
#include <cassert>

struct Foo
{ 
    Foo() {}
    Foo(std::size_t i) : i(i) {}
    std::size_t i;
};

template <std::size_t... Is>
void setFoo(std::size_t i, Foo& foo, std::index_sequence<Is...>)
{
    ((i == Is && (foo = Foo{Is}, false)), ...);
}

int main()
{
    for (std::size_t i = 0; i < 10; i++)
    {
        Foo foo;
        setFoo(i, foo, std::make_index_sequence<10>{});
        assert(foo.i == i);
    }
}


0 commentaires