C ++ 11 auto。从float转换为long

时间:2017-01-02 15:37:15

标签: 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

1 个答案:

答案 0 :(得分:13)

不是你写的方式。首先,

auto foo = float(1234567891234.1234);

使用自动类型推导规则来推断RHS的类型,结果为float。完成此操作后,foo的类型为float并且它是一成不变的(C ++是statically typed,与Python不同)。下次写的时候

foo = long(1234567891234.1234);

foo的类型仍为float,并且不会神奇地更改为long

如果你想模仿&#34;改变&#34;您最多可以执行演员表的类型:

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

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个单独的变量。