[英]Casting all members of struct automatically
I have a template class which has a lot of variables, all of the same type我有一个模板 class 有很多变量,都是相同的类型
template<typename T>
struct Location
{
T lat;
T lon;
T alt;
// and roughly 20 variables more of type T
};
In my code T
is either float
or double
, depending on the precision I need.在我的代码中, T
是float
或double
,具体取决于我需要的精度。 Sometimes I need to cast between these two struct.有时我需要在这两个结构之间进行转换。 Thus I want to define a conversion operator因此我想定义一个转换运算符
template<typename A, typename B> operator Location<B> {
Location<B> ret;
// cast every variable in *this from type A to type B
return ret;
}
Since there are a lot of variables in Location
and it is very likely that I will need to add more variables to the struct in future, I do not want to write each cast by hand in my conversion operator.由于Location
中有很多变量,并且将来我很可能需要向结构添加更多变量,所以我不想在我的转换运算符中手动编写每个转换。
Thus, I want to know whether there is some automagically way to cast all variables in the struct?因此,我想知道是否有某种自动方式来转换结构中的所有变量?
I'm afraid there's not such a way.恐怕没有这种方法。 I would probably write templated copy constructor and assign each variable manually.我可能会编写模板复制构造函数并手动分配每个变量。 You'll do it just once now, and then everytime you add a new variable - it's not a big deal IMO.你现在只做一次,然后每次添加一个新变量 - 这不是什么大问题 IMO。
You cannot do that natively.你不能在本地做到这一点。
one function that you can write, which might be useful in another contexts (such as comparison) is a tie
/ as_tuple
method:您可以编写的一个 function 可能在其他上下文(例如比较)中有用的是tie
/ as_tuple
方法:
template<typename T>
struct Location
{
T lat;
T lon;
T alt;
// and roughly 20 variables more of type T
auto as_tuple() const { return std::tie(lat, lon, alt /*, ..*/); }
template <typename T2> operator Location<T2>() const
{
return std::make_from_tuple<Location<T2>>(as_tuple());
// return std::apply([](auto... args){ return Location<T2>{static_cast<T2>(args)...}; },
// as_tuple());
}
};
Personally i never had this usecase, but if all entries in that struct are of the same type shouldn't something like the following work?就我个人而言,我从来没有这个用例,但是如果该结构中的所有条目都是相同类型的,那么不应该像下面这样工作吗?
template<typename T>
struct Location {
T a;
T b;
T c;
template<typename B> operator Location<B>() {
if constexpr(std::is_same_v<T,B>) {
return *this;
}
Location<B> ret;
constexpr std::size_t count = sizeof(Location<T>)/sizeof(T);
static_assert(sizeof(Location<B>)==sizeof(B)*count);
for (std::size_t i=0;i<count;++i){
B b;
T a;
memcpy(&a, ((char*)this)+i*sizeof(T), sizeof(T));
b = static_cast<B>(a);
memcpy(((char*)&ret) + i*sizeof(B), &b, sizeof(B));
}
return ret;
}
};
I'm quite sure that somewhere in that monstrosity is UB or at least issues with memory alignment.我很确定那个怪物的某个地方是UB,或者至少是memory alignment的问题。
This obviously won't work with pointers or types/structs which contain pointers.这显然不适用于包含指针的指针或类型/结构。
There is no good way to do this... but here is a completely terrible way that should never be used and works only if Location
contains only T
instances.没有好的方法可以做到这一点......但是这是一种完全可怕的方法,永远不应该使用并且仅在Location
仅包含T
实例时才有效。 There may also be alignment issues .也可能存在alignment 问题。
template<typename B>
operator Location<B>() const {
Location<B> ret;
for (int i = 0; i <= (sizeof(Location<T>) / sizeof(T)); i++) {
*(&ret.lat + i) = B(*(&lat + i));
}
return ret;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.