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

dje*_*ent 1 c++ casting auto c++11

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

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

foo = long(1234567891234.1234);
cout << "foo: " << foo << endl;
Run Code Online (Sandbox Code Playgroud)

输出总是:

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

vso*_*tco 13

不是你写的方式.第一,

auto foo = float(1234567891234.1234);
Run Code Online (Sandbox Code Playgroud)

使用自动类型推导规则来推断RHS的类型,结果是float.一旦做到这一点,类型foofloat,它是一成不变的(C++是静态类型,例如不同的Python).当你下次写

foo = long(1234567891234.1234);
Run Code Online (Sandbox Code Playgroud)

foo的类型仍然是float,并没有神奇地改变为long.

如果要模拟类型的"更改",则最多可以执行强制转换:

 cout << "foo (as long): " << static_cast<long>(foo) << endl;
Run Code Online (Sandbox Code Playgroud)

或使用其他变量

long foo_long = foo; // again you may have a loss of precision 
Run Code Online (Sandbox Code Playgroud)

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

如果您可以访问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;
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

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';
}
Run Code Online (Sandbox Code Playgroud)

Live on Coliru

A std::unique_ptr<void>不能仅作为std::shared_ptr实现类型擦除工作.

当然,如果你真的不关心存储大小等,只需使用2个独立的变量.

  • @djent不,正如我在答案中所说,在程序期间,`foo`的类型将始终为`float`.在任何情况下都不能改变C++中变量的类型.你最接近的是使用[`std :: variant <float,long>`](http://en.cppreference.com/w/cpp/utility/variant)(C++ 17). (4认同)