2017-08-07 11 views
1

以下のような構造を使って、このように使うことができます。C++匿名構造への参照を渡すことができますか?

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

しかし、このようなとしての機能に匿名の構造体への参照を渡すことが可能です。その場合は

SomeFunc(gga); 

、どのような関数のシグネチャは次のようになりますか?私の考えは、構造の名前を付けることなくあなたが傾けることはできませんが、私はそれがわからないほど巧妙な方法があるかどうかを知りたかっただけです!

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

関数宣言で 'auto'を使いますか? –

+0

を言い換えて:あなたはこれを行うことができますが、**あなたは**あなたですか?宣言の中の名前を省略することは、受信関数の余分な定型文の価値があるのでしょうか?本当にそれから何を得るのですか? –

+0

@underscore_d宣言は何らかのライブラリやベンダー提供のコードなので、変更する危険はない可能性があります(外部ソースを持つヘッダーを編集することは常に悪い考えです)。 – Swift

答えて

4

これは動作するはずです:

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

はい、それは確かに私の質問に正確に答えました。いい考え!ありがとう... –

5

をコンパイラがdecltype機能サポートしている場合は、これを行うことができます(標準の一部を、私たちのすべては、それが行く方法を知っている。)

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

decltypeはテンプレート作成に非常に便利です。この場合、クラスの非静的メンバ名としてNMEADecodedSentence::GGAを使用することができます。

オープンテンプレートは使用可能ですが、安全ではありません。NMEADecodedSentence::GGAではなく、関数で使用されているフィールドと同じフィールドを含むものを提供しようとする可能性があります。これはアーキテクチャの機能または誤った機能です。

あなたはこのようにテンプレートを保護することができます。

#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は、コンパイル時エラーを生成する別の種類の引数でfooを提供する場合、(それが「静的」である理由です):std::is_same<>::valueがfalseになります。あなたにもこれを行うことができます

注:

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

が、前述のテンプレートがstatic_assert表現に修正することなく、このタイプの引数を受け付けません。 foo2()が動作します。

関連する問題