2017-10-12 4 views
0

J'essaie d'écrire une bibliothèque d'analyse dimensionnelle simple au moment de la compilation. Je veux créer une option de compilation pour supprimer tout ce que la bibliothèque fait sans changer le code. Donc essentiellement j'ai fait ma propre version des types primitifs et je veux les remplacer par les types primitifs réels si cette option est sélectionnée.Remplacement d'une classe de modèles par des types primitifs

Ceci est un exemple de travail minimal du code

#include <iostream> 
#include <stdint.h> 

#define DEBUG 
#ifdef DEBUG 
    template<int lenght, int time, int mass, int charge, int temperature, int amount, int intensity> 
    struct Dimensions { 
     static const int64_t LENGHT = lenght; 
     static const int64_t TIME = time; 
     static const int64_t MASS = mass; 
     static const int64_t CHARGE = charge; 
     static const int64_t TEMPERATURE = temperature; 
     static const int64_t AMOUNT = amount; 
     static const int64_t INTENSITY = intensity; 
    }; 

    typedef Dimensions< 0, 0, 0, 0, 0, 0, 0 > Adimensional; 
    typedef Dimensions< 1, 0, 0, 0, 0, 0, 0 > Length; 
    typedef Dimensions< 0, 1, 0, 0, 0, 0, 0 > Time; 

    template<typename Dims> class Int32 { 
    private: 
     int32_t m_value; 

    public: 
     inline Int32() : m_value(0) {} 

     inline Int32(int32_t value) : m_value(value) {} 

     inline int32_t value() { 
      return m_value; 
     } 
    }; 

    template<typename Dims> 
    Int32<Dims> inline operator+(Int32<Dims> &lhs, Int32<Dims> &rhs) { 
     return Int32<Dims>(lhs.value() + rhs.value()); 
    } 

    struct Unmatched_dimensions_between_operands; 

    template<typename DimsLhs, typename DimsRhs> 
    Unmatched_dimensions_between_operands inline operator+(Int32<DimsLhs> &lhs, Int32<DimsRhs> &rhs); 
#else 
    template<typename Dims> using Int32<Dims> = std::int32_t; 
#endif 

int main(int argc, char* argv[]) { 
    Int32<Time> a = 2; 
    Int32<Time> b = 5; 

    std::cout << (a + b).value() << "\n"; 
    return 0; 
} 

Lorsque je supprime la ligne #define DEBUG je reçois l'erreur de compilation

Error C2988 unrecognizable template declaration/definition 59 

Y at-il une bonne façon de remplacer une version du modèle de Int32 en le code avec un type primitif?

+2

"N'a pas fonctionné" * Qu'est-ce qui n'a pas fonctionné? quelle erreur avez-vous eu? * –

+0

et ne pas ellipsiser des pièces entières de l'exposition essentielle ... –

+0

Mais ... 'Int32' est un type de modèle? Qu'est-ce que 'Dims' pour' Int32'? Si 'Int32' est un type simple (pas de template), qu'en est-il de' using Int32 = std :: int32_t'? – max66

Répondre

1

Essayez:

template<typename Dims> using Int32 = std::int32_t; 

vous devez également définir Time (et probablement Adimensional et Length) en quelque sorte (peu importe comment, comme argument de modèle est jamais utilisé).

Edit: Votre programm ne fonctionne toujours pas, comme l'accès à un membre value de Int32 qui est bien sûr pas présent dans std::int32_t. Cependant, j'espère que cela vous met sur la bonne voie.

+0

Merci beaucoup! Ça a marché, mais je ne comprends pas vraiment pourquoi ça marche. Pourquoi le modèle sur Int32 n'est pas explicite? – mbtg

+0

Une définition de modèle d'alias ressemble à ceci: modèle en utilisant Alias ​​= Foo ; – Knoep

+0

Dans votre cas, vous n'utilisez tout simplement pas le paramètre template. – Knoep