2017-08-07 82 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会是假的。

注意,你可以这样做,以及:

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

但上述模板不会接受这种类型的参数没有修复到static_assert表达。 foo2()会起作用。