c++联合可以对它包含的数字执行数学运算吗?



是否有可能在c++中创建一个联合,让我做这样的事情…

union myTime {
long millis;
double seconds;
};

但是,让它以某种方式进行转换,以便如果我以毫秒为单位输入时间,然后调用秒,它将获取该数字并将其除以1000,或者相反,如果我以秒为单位输入数字,然后调用毫秒,它将将该数字乘以1000…

:

myTime.millis = 1340;
double s = myTime.seconds;

其中s等于1.34

myTime.seconds = 2.5;
long m = myTime.millis;

其中m = 2500

这可能吗?

union只是相同值(相同字节)的不同表示,因此您无法在其上定义任何智能逻辑。

在这种情况下,可以用转换函数定义class(用于初始化或获取数据)。

class myTime {
public:
myTime(long millis);
double as_seconds();
static void from_seconds(double seconds);
};

请注意,正如在其他答案中提到的,对于时间转换,您可以使用std::chrono对象(c++11及以上)

回答问题:联合是一种低级结构,它只允许多个对象表示存在于相同的内存空间中。在您的示例中,longdouble共享同一个地址。

然而,它们还不够智能,无法自动进行任何类型的对话。在大多数情况下,访问union的非活动成员实际上是未定义的行为(如果在标准布局对象中有一个公共初始序列,则有例外)。

即使行为是定义良好的,您将在double中看到的值将是double对表示1340所需的字节模式的解释。


如果您的问题是专门与将millis转换为seconds有关,根据您的示例,您是否考虑使用std::chrono::duration单元?这些单元是专门为自动完成时间单位之间的转换而设计的——并且您可以使用自定义表示(例如double)定义持续时间。

你的问题中的例子可以重写:

using double_seconds = std::chrono::duration<double>;
const auto millis = std::chrono::millis{1340};
const auto m = double_seconds{millis}; 
// m contains 1.340

如果你滥用类型系统,你可以:

union myTime {
double seconds;
class milli_t {
double seconds;
public:
milli_t &operator=(double ms) {
seconds = ms/1000.0;
return *this; }
operator double() const { return seconds * 1000; }
} millis;
};

现在如果你做了

myTime t;
t.millis = 1340;
double s = t.seconds;

s等于1.34

myTime t;
t.seconds = 2.5;
long m = t.millis;

m将是2500,完全符合您的要求。

当然,为什么要这样做还不清楚。

最新更新