38 votes

La génération d'une séquence de zéros au moment de la compilation

J'ai le problème suivant:

template< size_t... N_i >
class A
{
  public:

    // ...

    void foo()
    {
      bar( /* 0,...,0 <- sizeof...(N_i) many */);
    }
};

Je veux appeler une fonction bar et passent sizeof...(N_i) de nombreux arguments à tous les zéros, par exemple, bar(0,0,0) en cas sizeof...(N_i) == 3. Comment cela peut-il être mis en œuvre?

60voto

Columbo Points 11661
bar(((void)N_i, 0)...);

L'opérateur virgule en débarrasser N_i, rendement juste à la droite de la valeur de l'opérande (0). Le casting est pour éviter un avertissement à propos de l' N_i d'être mis au rebut.

9voto

skypjack Points 5516

En dépit de la sans doute intéressant de réponse par @Columbo, je veux suggérer une autre solution viable basé sur constexpr'd les variables de modèle:

 #include <cstddef> 

 template<std::size_t, std::size_t V>
 constexpr std::size_t repeat_value = V;

 template<std::size_t... N_i>
 class A {
     template<typename... Args>
     void bar(Args&&...) { }

 public:   
      void foo() {
           // repeat N_i times value 0
           bar(repeat_value<N_i, 0>...);
      }
 };

 int main() {
      A<0, 1, 2, 3, 4> a;
      a.foo();
 }

Je le trouve plus facile à lire au moins, même si elle est mauvaise en termes de performance au moment de la compilation.


Vous pouvez facilement généraliser comme il suit:

template<std::size_t, typename T, T V>
constexpr T repeat_value = V;

Le invokation dans le cas spécifique est ceci:

bar(repeat_value<N_i, int, 0>...);

2voto

nabla Points 360

Vous pouvez également utiliser des modèles pour simuler quelque chose de semblable. C'est très une solution de base et il suffit de créer une liste de 0s, mais il pourrait être étendu à générer d'autres séquences, si désiré.

template <size_t Unused>
struct Wrap {
  static constexpr size_t value = 0;
};

template <size_t... N_i>
class A {
public:
    void foo() {
        bar(Wrap<N_i>::value...);
    }
};

Qui va juste l'agrandir dans une liste de zéros de la même taille que le N_i arguments. Certes, l'interface est légèrement différente.

Pour un exemple complet, qui montre les valeurs des éléments qui le bar reçoit, voir ici: Live exemple

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X