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

标签 c++ c++11 casting auto

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

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

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

输出总是:

foo: 1.23457e+12
foo: 1.23457e+12

最佳答案

不是你写的那样。首先,

auto foo = float(1234567891234.1234);

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

foo = long(1234567891234.1234);

foo 的类型仍然是 float 并且没有神奇地更改为 long

如果你想模拟类型的“变化”,你最多可以执行一个转换:

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

或者使用一个额外的变量

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

但要注意浮点表示可能导致的精度损失。

如果您可以访问 C++17 编译器,则可以使用类型安全 union 体 std::variant<long, float> 在类型之间切换。如果没有,您可以使用普通的旧 union ,例如

#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;
}

Live on 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
}

Live on 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';
}

Live on Coliru

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

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

关于C++11 自动。从 float 转换为 long,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41429555/

相关文章:

c++ - 能否安全地将 char 数据存储在 int 数据类型中

c++ - 使用类成员作为成员函数的默认参数

c++ - 从 std::vector<Eigen::Vector3d> 到 std::vector<Eigen::Vector3f> 的转换

c++ - 在 C++ 中将两个具有相同长度的 int vector 转换为一个由 int 对组成的 vector

c++ - 从注册表中读取值 C++

C++ Armadillo 和 OpenMp : Parallelization of summation of outer products - define reduction for Armadillo matrix

ios - 无法转换类型 'UIViewController' 的值

c++ - 为什么 param_type 构造函数对于随机分布是显式的?

C++ 模板参数作为函数调用名称

c - 为什么要将指针转换为函数