C++11自动.从float转换为long

C++11 auto. convert from float to long

本文关键字:long 转换 float 自动 C++11      更新时间:2023-10-16

是否可以将foo从float转换为long(反之亦然)?

auto foo = float(1234567891234.1234);
cout << "foo: " << foo << endl;
foo = long(1234567891234.1234);
cout << "foo: " << foo << endl;

输出始终为:

foo:123457e+12foo:123457e+12

不是你写的那样。首先,

auto foo = float(1234567891234.1234);

使用自动类型推导规则来推断RHS的类型,结果为float。一旦完成,foo的类型就是float,并且它是固定的(C++是静态类型的,不像Python)。下次写时

foo = long(1234567891234.1234);

foo的类型仍然是CCD_ 4并且它没有神奇地改变为CCD_。

如果你想模仿一个类型的"变化",你最多可以进行一次铸造:

cout << "foo (as long): " << static_cast<long>(foo) << endl;

或者使用额外的可变

long foo_long = foo; // again you may have a loss of precision 

但是要意识到由于浮点表示可能导致的精度损失。

如果您有权访问C++17编译器,则可以使用类型安全并集std::variant<long, float>在类型之间切换。如果没有,你可以使用像这样的简单的旧联盟

#include <iostream>
union Foo
{
float f;
long l;
};
int main()
{
Foo foo;
foo.f = float(1234567891234.1234); // we set up the float member
std::cout << "foo: " << foo.f << std::endl;
foo.l = long(1234567891234.1234); // we set up the long member
std::cout << "foo: " << foo.l << std::endl;
}

在Coliru上直播

或者,你可以使用像这样的类型擦除技术

#include <iostream>
int main()
{
void *foo; // we will store the object via this pointer
foo = new int{42};
std::cout << *(int*)foo << 'n';
operator delete(foo); // don't do delete foo, it is undefined behaviour
foo = new float{42.42};
std::cout << *(float*)foo << 'n';
operator delete(foo); // don't do delete foo, it is undefined behaviour
}

在Coliru上直播

上面代码的现代版本可以用类似std::shared_ptr的重写

#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<void> foo{new int{42}};
std::cout << *(int*)foo.get() << 'n';
foo.reset(new float{42.42});
std::cout << *(float*)foo.get() << 'n';
}

在Coliru上直播

std::unique_ptr<void>不能工作,因为只有std::shared_ptr实现类型擦除。

当然,如果您并不真正关心存储大小等,只需使用两个单独的变量即可。