简体   繁体   English

带有 char[] 字段的 POD 结构的 constexpr 构造

[英]constexpr construction of a POD struct with a char[] field

How can I make the function below constexpr ?如何使 function 低于constexpr

This is a function that I use to create a POD struct that is defined in a "C" header file that I cannot change.这是一个 function,我用它来创建一个 POD 结构,该结构在我无法更改的“C”header 文件中定义。

I ended up with the following static function helper (which works) to make these structs, I believe it is not constexpr , as the strncpy call violates constexpr .我最终得到了以下 static function 助手(有效)来制作这些结构,我相信它不是constexpr ,因为strncpy调用违反了constexpr

static auto makeWPTEntry(
    const char* name,
    double aLatDeg, double aLatMin, double aLonDeg,
    double aLonMin, char bSeven = false,
    double aCourse = 0, double aAzimuth = 0, double aDist = 0,
    int aETASecs = 0, int aMod = 0)->WPTEntry {
    auto result = WPTEntry{
        bSeven,
        {},
        (aLatDeg + aLatMin) / 60.0,
        (aLonDeg + aLonMin) / 60.0,
        aCourse, aAzimuth,
        aDist, aETASecs, aMod
    };
    strncpy(result.name, name, sizeof(result.name));
    return result;
}

I an struggling to make something along the following lines (which is constexpr ) - however I really need the non constexpr function signature with a const char* name parameter, Unfortunately, I don't know how to inline convert this const char* into a fixed sized array char const (&name)[SIZ_WAYPOINT_NAME] to be compatible with the struct field's constructor.我努力按照以下几行(即constexpr )做一些事情 - 但是我真的需要带有const char* name参数的非constexpr function 签名,不幸的是,我不知道如何内联将此const char*转换为固定大小的数组char const (&name)[SIZ_WAYPOINT_NAME]与结构字段的构造函数兼容。

constexpr auto makeWPTEntry(
    char const (&name)[SIZ_WAYPOINT_NAME],
    double aLatDeg, double aLatMin, double aLonDeg,
    double aLonMin, char bSeven = false,
    double aCourse = 0, double aAzimuth = 0,
    double aDist = 0,
    int aETASecs = 0, int aMod = 0)->WPTEntry {
    auto result = WPTEntry{
        bSeven,
        name,
        (aLatDeg + aLatMin) / 60.0,
        (aLonDeg + aLonMin) / 60.0,
        aCourse, aAzimuth,
        aDist, aETASecs, aMod
    };
    //strncpy(result.name, name, sizeof(result.name));
    return result;
}

The WPTEntry is a simple external C data structure. WPTEntry是一个简单的外部 C 数据结构。

#define SIZ_WAYPOINT_NAME 9

typedef struct {
    char    seven;
    char    name[SIZ_WAYPOINT_NAME];
    double  lat;        
    double  lon;        
    double  crs;        
    double  az2;        
    double  distance;   
    int     eta_secs;  
    int     mod;
} WPTEntry;

The way I create these structures is as follows:我创建这些结构的方式如下:

const auto wpt = makeWPTEntry("", -24.499, 0, -81.501, 0);

I asked something similar question before, however I never received an answer.我以前问过类似的问题,但我从来没有收到过答案。

I found the following from this site but I am not sure how I might be able to use it to adapt my parameter, perhaps its might be useful of not.我从这个站点找到了以下内容,但我不确定如何使用它来调整我的参数,也许它可能有用但没有用。

struct ArrayWrapper
{
   char const *address_;
   size_t      length_;

   template<int N>
   ArrayWrapper(char const (&array)[N])
   {
      address = &array[0];
      length_ = N;
   }
};

A bit of twiddling around std::integer_sequence and I got it:围绕std::integer_sequence进行了一些操作,我明白了:

#include <utility>
#include <iostream>

extern "C" {
    #define SIZ_WAYPOINT_NAME 9

typedef struct {
    char    seven;
    char    name[SIZ_WAYPOINT_NAME];
    double  lat;        
    double  lon;        
    double  crs;        
    double  az2;        
    double  distance;   
    int     eta_secs;  
    int     mod;
} WPTEntry;

};

template<std::size_t N, std::size_t... I>
constexpr WPTEntry makeWPTEntry_in(
        char const (&name)[N],
        double aLatDeg, double aLatMin, double aLonDeg,
        double aLonMin, char bSeven,
        double aCourse, double aAzimuth,
        double aDist,
        int aETASecs, int aMod,
        std::index_sequence<I...>) {
    return WPTEntry{
        bSeven,
        { name[I]... },
        (aLatDeg + aLatMin) / 60.0,
        (aLonDeg + aLonMin) / 60.0,
        aCourse, aAzimuth,
        aDist, aETASecs, aMod
    };
}

template<std::size_t N, typename Indices = std::make_index_sequence<N>>
constexpr WPTEntry makeWPTEntry(
            char const (&name)[N],
            double aLatDeg, double aLatMin, double aLonDeg,
            double aLonMin, char bSeven = false,
            double aCourse = 0, double aAzimuth = 0,
            double aDist = 0,
            int aETASecs = 0, int aMod = 0) {
    return makeWPTEntry_in(name, 
        aLatDeg, aLatMin, aLonDeg,
        aLonMin, bSeven,
        aCourse, aAzimuth,
        aDist,
        aETASecs, aMod,
        Indices{});
}

int main() {
    const auto wpt = makeWPTEntry("", -24.499, 0, -81.501, 0);
}

But really, be a man and copy it:但实际上,做一个男人并复制它:

template<std::size_t N>
constexpr WPTEntry makeWPTEntry(
            char const (&name)[N],
            double aLatDeg, double aLatMin, double aLonDeg,
            double aLonMin, char bSeven = false,
            double aCourse = 0, double aAzimuth = 0,
            double aDist = 0,
            int aETASecs = 0, int aMod = 0) {
    auto r = WPTEntry{
        bSeven,
        { 0 },
        (aLatDeg + aLatMin) / 60.0,
        (aLonDeg + aLonMin) / 60.0,
        aCourse, aAzimuth,
        aDist, aETASecs, aMod
    };
    for (size_t i = 0; i < N; ++i) {
        r.name[i] = name[i];
    }
    return r;
}

int main() {
    constexpr auto wpt = makeWPTEntry("abc", -24.499, 0, -81.501, 0);
    std::cout << wpt.name;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM