static_cast 是否影响简单类型浮点数的提升?
Does static_cast affect Boost for simple type float?
在Boost ODEINT库中,您可以找到很多static_cast
关键字,例如:
template<
class State ,
class Value = double ,
class Deriv = State ,
class Time = Value ,
class Algebra = typename algebra_dispatcher< State >::algebra_type ,
class Operations = typename operations_dispatcher< State >::operations_type ,
class Resizer = initially_resizer
>
class runge_kutta_dopri5: ....
{
...
typedef typename stepper_base_type::value_type value_type;
...
template< class System , class StateIn , class DerivIn , class StateOut , class DerivOut >
void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt_in , time_type t ,
StateOut &out , DerivOut &dxdt_out , time_type dt )
{
const value_type a2 = static_cast<value_type> ( 1 ) / static_cast<value_type>( 5 );
const value_type a3 = static_cast<value_type> ( 3 ) / static_cast<value_type> ( 10 );
const value_type a4 = static_cast<value_type> ( 4 ) / static_cast<value_type> ( 5 );
const value_type a5 = static_cast<value_type> ( 8 )/static_cast<value_type> ( 9 );
....
其中value_type
由模板决定。
我的问题是,如果 value_type
是像 double
这样的简单类型,那么 static_cast<value_type> ( 5 )
和 (double)5
之间有什么区别吗?我想知道他们为什么使用这样的铸造。 value_type
是double&
还是double&&
是一样的吗?
没有区别。
他们选择 C++ 风格的转换,因为它们更安全。
C 风格的强制转换可以执行任何重新解释的强制转换,这甚至可能无法远程执行预期的操作,并且当它发生在高度悄无声息的深处时尤其危险像 Boost ODEINT 这样的 geneirc 库
简单示例:
struct FixedPoint {
int x;
FixedPoint(int x):x(x) {}
operator double() const { return x/10.0; }
};
// deep in the bowels of a library, this happens:
double test = static_cast<double>(FixedPoint(42)); // ok 4.2
但是,在其他地方,在一些不太幸运的代码库中:
struct FixedPoint {
int x;
FixedPoint(int x):x(x) {}
double as_double() const { return x/10.0; }
};
// oops, good thing the compile catches this!
double test = static_cast<double>(FixedPoint(42)); // COMPILE ERROR
想象一下如果那是写出来的大屠杀
double test = (double) (FixedPoint(42)); // silent reinterpret_cast<double>
简而言之,在 C++ 中,永远不会 编写 C 风格的强制转换。这没有用。
- Regular cast vs. static_cast vs. dynamic_cast
- When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?
在Boost ODEINT库中,您可以找到很多static_cast
关键字,例如:
template<
class State ,
class Value = double ,
class Deriv = State ,
class Time = Value ,
class Algebra = typename algebra_dispatcher< State >::algebra_type ,
class Operations = typename operations_dispatcher< State >::operations_type ,
class Resizer = initially_resizer
>
class runge_kutta_dopri5: ....
{
...
typedef typename stepper_base_type::value_type value_type;
...
template< class System , class StateIn , class DerivIn , class StateOut , class DerivOut >
void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt_in , time_type t ,
StateOut &out , DerivOut &dxdt_out , time_type dt )
{
const value_type a2 = static_cast<value_type> ( 1 ) / static_cast<value_type>( 5 );
const value_type a3 = static_cast<value_type> ( 3 ) / static_cast<value_type> ( 10 );
const value_type a4 = static_cast<value_type> ( 4 ) / static_cast<value_type> ( 5 );
const value_type a5 = static_cast<value_type> ( 8 )/static_cast<value_type> ( 9 );
....
其中value_type
由模板决定。
我的问题是,如果 value_type
是像 double
这样的简单类型,那么 static_cast<value_type> ( 5 )
和 (double)5
之间有什么区别吗?我想知道他们为什么使用这样的铸造。 value_type
是double&
还是double&&
是一样的吗?
没有区别。
他们选择 C++ 风格的转换,因为它们更安全。
C 风格的强制转换可以执行任何重新解释的强制转换,这甚至可能无法远程执行预期的操作,并且当它发生在高度悄无声息的深处时尤其危险像 Boost ODEINT 这样的 geneirc 库
简单示例:
struct FixedPoint {
int x;
FixedPoint(int x):x(x) {}
operator double() const { return x/10.0; }
};
// deep in the bowels of a library, this happens:
double test = static_cast<double>(FixedPoint(42)); // ok 4.2
但是,在其他地方,在一些不太幸运的代码库中:
struct FixedPoint {
int x;
FixedPoint(int x):x(x) {}
double as_double() const { return x/10.0; }
};
// oops, good thing the compile catches this!
double test = static_cast<double>(FixedPoint(42)); // COMPILE ERROR
想象一下如果那是写出来的大屠杀
double test = (double) (FixedPoint(42)); // silent reinterpret_cast<double>
简而言之,在 C++ 中,永远不会 编写 C 风格的强制转换。这没有用。
- Regular cast vs. static_cast vs. dynamic_cast
- When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?