哪个是记录static_cast的惯用方法?

时间:2013-12-10 15:13:11

标签: c++ casting static-cast

我理解(MyType)fooMyType(foo)static_cast<MyType>(foo)有些相似,因为前两个成为最后一个(编辑:我已被纠正。前一句话是不真实的。)我的问题是哪个是惯用版?背景是一个考虑因素吗?

因为我知道在C ++中不喜欢C样式转换,所以它取决于功能转换和static_cast。

3 个答案:

答案 0 :(得分:3)

在我的书中使用显式演员是惯用的。

static_cast<MyType>(foo)优于(MyType)foo,因为它更具表现力和表达能力。这在(MyType)foo 意味着它意味着什么的许多情况下尤其有用。例如,在您的示例中,这些案例可能根本不会减少到static_cast,而是reinterpret_cast

在代码审查中,我会拒绝非算术类型的所有C风格的演员表。

答案 1 :(得分:2)

首先,虽然是C ++的新手,但功能样式转换 C风格的转换。他们做同样的事情。

C风格演员表首先尝试static_cast,如果这不起作用,reinterpret_cast 1 。这很糟糕,因为旨在进行简单更改的操作可能会变得非常奇怪。

例如,假设您有一个Foo* f和一个完全不相关的类Bar。您可以(Bar*)f,它会默默地将*f重新解释为Bar,可能会导致未定义的行为。

如果static_castFoo是相关类型,则Bar仅适用于此情况。

现在,即使static_cast也可能过于强大,因此我经常会编写一个implicit_castnon_cast模板来转换 - 无需转换。同样,我写as_const添加const而不是const_cast(可以添加和删除const,删除const远比explicit更危险。加上它。)

在C ++中没有明确的安全强制转换有点烦人,我不知道如何编写一个(一个将执行static_cast构造函数,但不会强制转换#34; down&#34;像{{1}}这样的类型层次结构。)


1 这是一种过度简化,但足够接近真实。

答案 2 :(得分:2)

前两个(MyType)fooMyType(foo)具有相同的含义。意义的含义在很大程度上取决于MyTypefoo的类型。例如:

((int)1.0);   // a static_cast
int i = 0;
((char*)&i);  // a reinterpret_cast
const int j = 0;
((int*)&j);   // a const_cast
((char*)&j);  // a combination of a const_cast and a reinterpret_cast

typedef char *CharPtr;
CharPtr(&j);  // a C-style cast, same as ((CharPtr)&j) or ((char*)&j)

因此,C风格的演员表不是首选的原因是C风格演员阵容做了很多不同的事情。 C ++提供了区分它们的方法。在很多情况下,这样可以更容易理解代码,特别是在用C ++编写通用代码之后,类型不像C语言那样明显。

这就是为什么static_cast等在C ++中首选的原因 - 它们为读者明确规定了一些可能难以为自己解决的问题。顺便说一句,static_cast也做了一些不同的事情,所以原则上你可能想要更多不同的演员阵容。但是static_cast至少比C风格的演员要少。

带有一个参数的功能样式转换是 C风格的转换。在所有情况下,它们在标准中明确定义为完全相同的东西。

现在,在某些情况下,您可以在使用函数语法编写时接受C样式转换,但在使用C转换语法编写时则不行。这通常是在目标类型是一个类时,很明显将调用哪个构造函数。在这种情况下,std::vector<int>(0)static_cast<std::vector<int>>(0)短,并且通常更清晰,因为它可以被读作构造函数调用。但它仍然具有与写(std::vector<int>)0相同的“危险”。如果您以这种方式编写每个转换,那么最终您会不小心从指针类型中删除const