C ++中的类型调整问题 [英] type-punning issue in c++

查看:108
本文介绍了C ++中的类型调整问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个以bool作为模板参数Dyanmic的模板类.无论参数是true还是false,它都具有完全相同的数据成员.它们只是成员功能不同.

I have a template class with a bool as its template parameter Dyanmic. Whether the parameter is true or false it has the exact same data members. they just differ in their member functions.

在一种情况下,我需要暂时将其转换为另一种,而不是使用复制/移动构造函数.所以我求助于打字.为了确保它引起问题,我使用了两个static_asserts:

There is one situation that I need to convert one to another temporarily, instead of using a copy/move constructor. So I resorted to type-punning. To make sure that it cause an issue I used two static_asserts:

d_true=Dynamic<true>(...);
...
static_assert(sizeof(Dynamic<true>)==sizeof(Dynamic<false>),"Dynamic size mismatch");
static_assert(alignof(Dynamic<true>)==alignof(Dynamic<false>),"Dynamic align mismatch");
Dynamic<false>& d_false=*reinterpret_cast<Dynamic<false>*>(&d_true);
...

所以我认为我正在做的事是安全的,如果有什么要出错的地方,编译器会给我一个static_assert错误.但是,gcc发出警告:

So I think what I am doing is safe, and if anything is about to go wrong the compiler will give me a static_assert error. However, gcc gives a warning:

警告:取消引用类型化指针会破坏严格别名规则[-Wstrict-aliasing]

warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

我的问题是双重的:实现这一目标的最佳方法是什么?如果是这样,怎么能说服gcc它是安全的,并摆脱警告?

My question is twofold: is what I am doing the best way to achieve this? If it is, how can convince gcc it is safe, and get rid of the warning?

推荐答案

一种明显的可能性是将两者通用的数据分离到自己的类(或结构)中,然后在需要时从对象中获取它.

One obvious possibility would be to separate the data that's common to both out into its own class (or struct), then grab that from the the object when you need it.

struct Common {
// ...
};

template <bool b>
class Dynamic { 
    Common c;
public:
    Common &get_data() { return c; }
    // ...
};

从那里开始,其余的工作就很明显了-当您需要Dynamic<whatever>中的数据时,您呼叫get_data()然后离开.

From there, the rest seems fairly obvious--when you need the data from the Dynamic<whatever>, you call get_data() and off you go.

当然,一般主题也有所不同-例如,您可以改用继承:

Of course, there are variations on the general theme as well--for example, you could use inheritance instead:

struct Common { /* ... */ };

template <bool t>
class Dynamic : public Common {
    // ...
};

这消除了先前版本中每次引用公共数据所需的额外c.,但是(至少在我看来)继承可能为此付出了很高的代价.

This eliminates the extra c. the previous version would need for every reference to the common data, but (at least in my opinion) inheritance is probably too high a price to pay for that.

这篇关于C ++中的类型调整问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆