具有 char[] 字段的 POD 结构的 constexpr 构造
constexpr construction of a POD struct with a char[] field
如何实现下面的功能constexpr
?
这是我用来创建 POD 结构的函数,该结构在我无法更改的“C”头文件中定义。
我最终使用以下静态函数助手(有效)来制作这些结构,我相信它不是 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;
}
我正在努力按照以下几行(constexpr
)做一些事情 - 但是我真的需要带有 const char* name
参数的非 constexpr
函数签名,不幸的是,我不知道如何将此 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;
}
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;
我创建这些结构的方式如下:
const auto wpt = makeWPTEntry("", -24.499, 0, -81.501, 0);
我之前问过类似的问题question,但是我从来没有得到答案。
我从 this site 中找到了以下内容,但我不确定如何使用它来调整我的参数,也许它可能有用。
struct ArrayWrapper
{
char const *address_;
size_t length_;
template<int N>
ArrayWrapper(char const (&array)[N])
{
address = &array[0];
length_ = N;
}
};
经过一番折腾 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);
}
但真的,做人,抄袭:
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;
}
如何实现下面的功能constexpr
?
这是我用来创建 POD 结构的函数,该结构在我无法更改的“C”头文件中定义。
我最终使用以下静态函数助手(有效)来制作这些结构,我相信它不是 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;
}
我正在努力按照以下几行(constexpr
)做一些事情 - 但是我真的需要带有 const char* name
参数的非 constexpr
函数签名,不幸的是,我不知道如何将此 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;
}
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;
我创建这些结构的方式如下:
const auto wpt = makeWPTEntry("", -24.499, 0, -81.501, 0);
我之前问过类似的问题question,但是我从来没有得到答案。
我从 this site 中找到了以下内容,但我不确定如何使用它来调整我的参数,也许它可能有用。
struct ArrayWrapper
{
char const *address_;
size_t length_;
template<int N>
ArrayWrapper(char const (&array)[N])
{
address = &array[0];
length_ = N;
}
};
经过一番折腾 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);
}
但真的,做人,抄袭:
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;
}