2017-08-07 2 views
1

En utilisant la structure ci-dessous, je peux l'utiliser comme ceci par exemple.C++ Passer une référence à une structure anonyme - pouvez-vous?

NMEADecodedSentence s; 
auto & gga = s.GGA; 
auto alt = gga.Alt; 

Mais est-il possible de passer une référence à une structure anonyme à une fonction telle que:

SomeFunc(gga); 

Si oui, quel serait le look de signature de la fonction comme? Mes pensées ne vous manquent pas sans nommer les structures mais je voulais juste savoir s'il y avait une façon intelligente de le faire que je ne savais pas!

struct NMEADecodedSentence 
    { 
     GNSSSentenceType Type; 
     GNSSTalkerId TalkerId; 
     union 
     { 
      struct 
      { 
       char Time[10];   // UTC time - hhmmss.ss 
       char Lat[13];   // Latitude (degrees & minutes) - ddmm.mmmmm 
       char NS;    // North/South indicator 
       char Long[14];   // Longitude (degrees & minutes) - dddmm.mmmmm 
       char EW;    // East/West indicator 
       uint8_t Quality;  // Quality indicator for position fix 
       uint8_t NumSV;   // Number of satellites used (0-12) 
       float HDOP;    // Horizontal Dilution of Precision 
       float Alt;    // Altitude above mean sea level - meters 
      }GGA; 
      struct // Recommended minimum data 
      { 
       char Time[10];   // UTC time - hhmmss.ss 
       char Status;   // Status, V = Navigation receiver warning, A = Data valid 
       char Lat[13];   // Latitude (degrees & minutes) - ddmm.mmmmm 
       char NS;    // North/South indicator 
       char Long[14];   // Longitude (degrees & minutes) - dddmm.mmmmm 
       char EW;    // East/West indicator 
       float Spd;    // Speed over ground - knots 
       float COG;    // Course over ground - degrees 
       char Date[7];   // UTC Date - ddmmyy 
      }RMC; 
      struct // Course over ground and ground speed 
      { 
       float COGT;    // Course over ground (true) - degrees 
       float COGM;    // Course over ground (magnetic) - degrees 
       float Kph;    // Speed over ground - kph 
      }VTG; 
     }; 
    }; 
+1

Voulez-vous utiliser 'auto' dans une déclaration de fonction? –

+0

pour paraphraser: Vous pouvez le faire, mais ** devrait ** vous? Est-ce que l'omission du nom dans la déclaration vaut vraiment le coup de pouce supplémentaire dans les fonctions de réception? Qu'est-ce que vous en retirerez, vraiment? –

+0

@underscore_d il est possible que la déclaration soit une sorte de bibliothèque ou un code fourni par le fournisseur, donc il ne risque pas de le changer (toujours une mauvaise idée d'éditer les en-têtes qui ont une source externe) – Swift

Répondre

4

Cela devrait fonctionner:

void f(decltype(NMEADecodedSentence::GGA)& gga) 
{ 
    ... 
} 
+0

Oui, cela a effectivement répondu exactement à ma question. Bien pensé! Merci... –

5

Vous pouvez le faire, si le compilateur prend en charge decltype fonction (partie de la norme, mais nous savons tous comment ça se passe ..)

char foo2(decltype (NMEADecodedSentence::GGA) & param) 
{ 
    return param.EW; 
} 

decltype est très utile pour la construction de modèles. NMEADecodedSentence::GGA en tant que nom de membre non statique de la classe est utilisable dans ce cas.

Le modèle ouvert est utilisable, mais est de type non sécurisé, car vous pouvez essayer d'offrir tout ce qui contient les mêmes champs utilisés dans la fonction au lieu de NMEADecodedSentence::GGA. Cela peut être une caractéristique ou un défaut d'architecture.

Vous pouvez protéger modèle comme ceci:

#include <type_traits> 

template<typename T> 
char foo(T &a) 
{ 
    static_assert(std::is_same<T,decltype (NMEADecodedSentence::GGA)>::value || 
       std::is_same<T,decltype (NMEADecodedSentence::RMC)>::value, 
       "Wrong type of foo() argument"); 
    return a.EW; 
} 

static_assert produirait une erreur de compilation (c'est pourquoi il est « statique »), si vous fournissez foo avec l'argument de type différent: std::is_same<>::value serait faux.

Notez que vous pouvez le faire ainsi:

struct GGAType : public decltype (NMEADecodedSentence::GGA) 
{ 
}; 

mais modèle mentionné ci-dessus ne sera pas accepter l'argument de ce type sans une solution à l'expression de static_assert. foo2() fonctionnerait.