static_cast 和 Implicit_cast 有什么区别?

发布于 2024-07-21 04:48:20 字数 63 浏览 12 评论 0原文

什么是implicit_cast? 我什么时候应该选择implicit_cast而不是static_cast?

What is implicit_cast? when should I prefer implicit_cast rather than static_cast?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

羅雙樹 2024-07-28 04:48:20

我正在复制我对 在另一个地方回答此评论

您可以使用static_cast进行向下转换。 implicit_cast 则不然。 static_cast 基本上允许您进行任何隐式转换,此外还允许您执行任何隐式转换的反向转换(达到某些限制。如果涉及虚拟基类,则无法进行向下转换)。 但是implicit_cast接受隐式转换。 如果 T 仅具有 U 的显式构造函数,则不进行向下转换,不进行 void*->T*,不进行 U->T

如果 T 仅具有 U 的显式构造函数, 强制转换和转换之间的区别。 下面没有进行强制转换,

int a = 3.4;

但发生了从 double 到 int 的隐式转换。 像“隐式转换”这样的事情并不存在,因为转换始终是显式转换请求。 boost::implicit_cast 的名称构造是“使用隐式转换进行转换”的完美组合。 现在 boost::implicit_cast 的整个实现是这样的(解释此处):

template<typename T> struct identity { typedef T type; };
template<typename Dst> Dst implicit_cast(typename identity<Dst>::type t)
{ return t; }

这个想法是为参数t使用非推导上下文。 这将避免像下面这样的陷阱:

call_const_version(implicit_cast(this)); // oops, wrong!

所期望的是像这样写出来

call_const_version(implicit_cast<MyClass const*>(this)); // right!

编译器无法推断出模板参数 Dst 应该命名什么类型,因为它首先必须知道 identity< ;Dst> 是,因为它是用于推导的参数的一部分。 但它又取决于参数Dstidentity可以显式地专门用于某些类型)。 现在,我们得到了一个循环依赖,标准只是说这样的参数是非推导的上下文,并且必须提供显式的模板参数。

I'm copying over from a comment i made to answer this comment at another place.

You can down-cast with static_cast. Not so with implicit_cast. static_cast basically allows you to do any implicit conversion, and in addition the reverse of any implicit conversion (up to some limits. you can't downcast if there is a virtual base-class involved). But implicit_cast will only accept implicit conversions. no down-cast, no void*->T*, no U->T if T has only explicit constructors for U.

Note that it's important to note the difference between a cast and a conversion. In the following no cast is going on

int a = 3.4;

But an implicit conversion happens from double to int. Things like an "implicit cast" don't exist, since a cast is always an explicit conversion request. The name construct for boost::implicit_cast is a lovely combination of "cast using implicit conversions". Now the whole implementation of boost::implicit_cast is this (explained here):

template<typename T> struct identity { typedef T type; };
template<typename Dst> Dst implicit_cast(typename identity<Dst>::type t)
{ return t; }

The idea is to use a non-deduced context for the parameter t. That will avoid pitfalls like the following:

call_const_version(implicit_cast(this)); // oops, wrong!

What was desired is to write it out like this

call_const_version(implicit_cast<MyClass const*>(this)); // right!

The compiler can't deduce what type the template parameter Dst should name, because it first must know what identity<Dst> is, since it is part of the parameter used for deduction. But it in turn depends on the parameter Dst (identity could be explicitly specialized for some types). Now, we got a circular dependency, for which the Standard just says such a parameter is a non-deduced context, and an explicit template-argument must be provided.

勿忘初心 2024-07-28 04:48:20

如果 implcit_cast 对于您的情况来说足够了,那么更喜欢 implcit_cast 。 implicit_cast 不如 static_cast 强大且安全。

例如,使用 static_cast 可以从基指针向下转换为派生指针,但不能使用implicit_cast。 两种演员阵容都可以采用相反的方式。 然后,当从基类转换为派生类时,请使用implicit_cast,因为如果您混淆了两个类,它可以保证您的安全。

还要记住,通常不需要implicit_cast。 当implicit_cast使用时,大多数情况下根本不使用强制转换,这就是“隐式”的来源。 仅在必须精确控制表达式类型的特殊情况下才需要使用implicit_cast,例如以避免重载。

Prefer implcit_cast if it is enough in your situation. implicit_cast is less powerful and safer than static_cast.

For example, downcasting from a base pointer to a derived pointer is possible with static_cast but not with implicit_cast. The other way around is possible with both casts. Then, when casting from a base to a derived class, use implicit_cast, because it keeps you safe if you confuse both classes.

Also keep in mind that implicit_cast is often not needed. Using no cast at all works most of the time when implicit_cast does, that's where 'implicit' comes from. implicit_cast is only needed in special circumstances in which the type of an expression must be exactly controlled, to avoid an overload, for example.

黎歌 2024-07-28 04:48:20

implicit_cast 将一种类型转换为另一种类型,并且可以通过编写隐式转换函数进行扩展,以从一种类型转换为另一种类型。

例如

int i = 100;
long l = i;

int i = 100;
long l = implicit_cast<long>(i);

是完全相同的代码

,但是您可以通过重载 implicit_cast 为您自己的类型提供自己的隐式转换,如下所示

template <typename T>
inline T implicit_cast (typename mpl::identity<T>::type x) 
{
    return x;
}

请参阅此处 boost/implicit_cast.hpp 了解更多

希望这会有所帮助

编辑

此页面还讨论了implicit_cast New C++

另外,static_cast的主要功能是执行不改变或不改变的操作。从一种类型到另一种类型的语义转换。 类型发生变化,但值保持相同,例如

void *voidPtr = . . .
int* intPtr = static_cast<int*>(voidPtr);

我想查看这个 void 指针,就好像它是一个 int 指针一样,该指针不会改变,并且在幕后 voidPtr 具有与 intPtr 完全相同的值。
implicit_cast,类型发生变化,但转换后的值也可能不同。

implicit_cast transforms one type to another, and can be extended by writing implicit cast functions, to cast from one type to another.

e.g.

int i = 100;
long l = i;

and

int i = 100;
long l = implicit_cast<long>(i);

are exactly the same code

however you can provide your own implicit casts for your own types, by overloading implicit_cast like the following

template <typename T>
inline T implicit_cast (typename mpl::identity<T>::type x) 
{
    return x;
}

See here boost/implicit_cast.hpp for more

Hope this helps

EDIT

This page also talks about implicit_cast New C++

Also, the primary function of static_cast is to perform an non changing or semantic transformation from one type to another. The type changes but the values remain identical e.g.

void *voidPtr = . . .
int* intPtr = static_cast<int*>(voidPtr);

I want to look at this void pointer, as if it was an int pointer, the pointer doesn't change, and under the covers voidPtr has exactly the same value as intPtr.
An implicit_cast, the type changes but the values after the transformation can be differnet too.

云归处 2024-07-28 04:48:20

隐式转换、显式转换和 static_cast 都是不同的东西。 但是,如果可以隐式转换,则可以显式转换;如果可以显式转换,则可以静态转换。 然而,在另一个方向则不然。 隐式强制转换和隐式强制转换之间存在完全合理的关系
静态转换。 前者是后者的子集。

详细信息请参见 C++ 标准第 5.2.9.3 节

否则,表达式 e 可以是
使用显式转换为类型 T
static_- 形式的 static_cast
如果声明 T t(e),则强制转换 (e);
对于某些发明来说是格式良好的
临时变量 t (8.5)。

C++ 鼓励使用 static_casts,因为它使转换在程序中“可见”。 强制转换本身的使用表明了一些程序员强制执行的规则,值得一看,因此最好使用 static_cast。

Implicit conversions, explicit conversions and static_cast are all different things. however, if you can convert implicitly, you can convert explicitly, and if you can convert explicitly, you can cast statically. The same in the other direction is not true, however. There is a perfectly reasonable relationship between implicit casts and
static casts. The former is a subset of the the latter.

See section 5.2.9.3 of the C++ Standard for details

Otherwise, an expression e can be
explicitly converted to a type T using
a static_cast of the form static_-
cast(e) if the declaration T t(e);
is well-formed, for some invented
temporary variable t (8.5).

C++ encourages use of static_casts because it makes the conversion 'visible' in the program. Usage of casts itself indicates some programmer enforced rule which is worth a look so better use static_cast.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文