2 votes

Défaut d'accumulation des constantes de temps de compilation

J'essaie de créer une variante int vecteurs d'arguments et effectuer + opérateurs sur eux.

Par exemple :

vec<1,2,3> v1;
vec<4,5>   v2;
auto res = v1+v2;
res.print(); // should print 5 7 3 vec<5,7,3> is the result.

Et maintenant, je veux créer une structure vecSum qui fera la somme des vecteurs qui lui sont donnés ;

namespace ex {

    template<int... N>
    struct vec
    {
        static const int size = sizeof...(N);
        void print() {
            ((std::cout << N << " "), ...);
        }
    };

    template<int...N, int...M, int ...S>
    auto add(vec<N...>, vec<M...>, std::index_sequence<S...>) {
        constexpr int arr1[sizeof...(S)]{ N... };
        constexpr int arr2[sizeof...(S)]{ M... };
        return vec<(arr1[S] + arr2[S])...>{};
    }

    template<int...N, int...M>
    auto operator+(vec<N...> v1, vec<M...> v2) {
        constexpr size_t size = std::max(sizeof...(N), sizeof...(M));
        return add(v1, v2, std::make_index_sequence<size>{});
    }

    template<typename... Args>
    auto all(Args... args) { return (... + args); }

    template<typename... Ts>
    struct vecSum
    {
        static constexpr auto res = all(Ts);
    };
}

Ce test fonctionne bien :

ex::vec<1, 2, 3> v1;
ex::vec<4, 5> v2;
ex::vec<2> v3;
auto r = ex::all(v1,v2,v3);
r.print();

This prints 7 7 3;

Ce que je veux réaliser, c'est :

vecSum<vec<1,3,4>, vec<3>, vec<3,4,5>> z;
z::res.print(); and I expect 7 7 9

Au lieu de cela, j'ai cette erreur :

error C2275: 'Ts': illegal use of this type as an expression
error C2119: 'res': the type for 'auto' cannot be deduced from an empty initializer

Quelqu'un peut-il m'indiquer ce qui ne va pas ici ? Je sais que j'essaie de passer des types de paramètres pack Ts en tant qu'expression, existe-t-il une solution de contournement ou un correctif pour cela ?

6voto

max66 Points 4276

Je vois quelques petits problèmes dans votre code...


  1. étendre Ts

En vecSum vous définissez res comme suit

static constexpr auto res = all(Ts);

Vous devez vous développer Ts comme suit

// ...............................VVVVV
static constexpr auto res = all(Ts{}...);

  1. std::index_sequence contient std::size_t pas int valeurs

Su add() est défini comme suit

template<int...N, int...M, int ...S>
auto add(vec<N...>, vec<M...>, std::index_sequence<S...>) 

Mais le S... Les valeurs sont std::size_t

// ........................VVVVVVVVVVV
template<int...N, int...M, std::size_t ...S>
auto add(vec<N...>, vec<M...>, std::index_sequence<S...>) 

ou la déduction des modèles ne fonctionne pas.


  1. constexpr fonctions

Si vecSum doit être constexpr vous devez définir toutes les fonctions nécessaires ( add() , all() , operator+() ) comme constexpr .


  1. print() const

La méthode vec::print() est meilleur const étant donné que vous voulez imprimer une constexpr vecSum::res valeur.


Voici un exemple complet de compilation corrigée

#include <utility>
#include <iostream>
#include <type_traits>

namespace ex {

    template<int... N>
    struct vec
    {
        static const int size = sizeof...(N);
        void print() const {
            ((std::cout << N << " "), ...);
        }
    };

    template<int...N, int...M, std::size_t ...S>
    constexpr auto add(vec<N...>, vec<M...>, std::index_sequence<S...>) {
        constexpr int arr1[sizeof...(S)]{ N... };
        constexpr int arr2[sizeof...(S)]{ M... };
        return vec<(arr1[S] + arr2[S])...>{};
    }

    template<int...N, int...M>
    constexpr auto operator+(vec<N...> v1, vec<M...> v2) {
        constexpr size_t size = std::max(sizeof...(N), sizeof...(M));
        return add(v1, v2, std::make_index_sequence<size>{});
    }

    template<typename... Args>
    constexpr auto all(Args... args) { return (... + args); }

    template<typename... Ts>
    struct vecSum
    {
        static constexpr auto res = all(Ts{}...);
    };
}

int main ()
 { 

   ex::vecSum<ex::vec<1,3,4>, ex::vec<3>, ex::vec<3,4,5>> z;
   z.res.print();
 }

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