函数式演员被视为有害吗?

时间:2014-04-12 03:06:10

标签: c++ casting

据我所知,通常C风格的演员阵容被认为是有害的。所以,给定一个班级Widget

class Widget{
public:
  explicit Widget(Gizmo gizmo);
};

我可以调用这样的函数:

functionThatTakesAWidget((Widget) gizmo);

使用C风格的演员。或者我可以使用函数式转换来编写它:

functionThatTakesAWidget(Widget(gizmo));

但这完全相同。所以没有更好或更糟。如果我真的想避免使用C风格的演员,我可以写:

functionThatTakesAWidget(static_cast<Widget>(gizmo));

但考虑到课程Doohickey

class Doohickey {
public:
  Doohickey(Gizmo left_gizmo, Gizmo right_gizmo);
};

我无法避免写作:

functionThatTakesADoohickey(Doohickey(left_gizmo, right_gizmo));

我认为这不算是“演员”。什么?但是这与功能风格的演员之间有什么区别?为什么这样可以,但功能风格的演员表不是?

3 个答案:

答案 0 :(得分:1)

避免C-Style演员表的原因是:

  • 明确指出发生了什么样的铸造,从而确保没有其他类型的铸造。
  • 使演员阵容更容易找到。

虽然功能风格的演员看起来更安全,但它实际上是伪装的C风格演员,所以它并没有真正添加任何东西。

显式背后的驱动原因是让编译器断言你的假设,而不是默默地做(有时)错误的事情。
恕我直言,一些纯粹主义者在他们的热情中走得很远。

答案 1 :(得分:0)

我不会将Widget(gizmo)称为“C式演员”。在C中,无论如何都不能转换为结构类型。 “C风格演员表”的主要问题是当指针或参考演员发生时。然后,C风格的演员表可能不明确或导致不明确的行为。

在我看来,值转换是与引用转换不同的概念,并且您不需要对两者使用相同的约定。

代码正在创建一个临时Widget,将gizmo传递给构造函数。我认为static_cast版本具有误导性,Widget(gizmo)很好。

顺便说一下,你可以让functionThatTakesADoohickey重载以获得Gizmostd::initializer_list<Gizmo>

答案 2 :(得分:0)

我相信:

C c;
(A)c

调用转换运算符&#34; C :: operator A()&#34;。当提供C时可以调用,但是需要A。例如:

void f(A const&) { ... }
f(c);

此外,

A(c)

调用构造函数:&#34; A :: A(const&amp; C)&#34;。

我相信如果你没有定义强制转换操作符,C ++可能会隐式调用构造函数来获取A.有时这是一个很大的灾难(让我们说这个构造函数格式化你的硬盘和离婚文件)。所以有两种补救措施:

class A {
public:
   explicit A(const& C);  // Don't call this when asking to cast to an A.
}

以及

static_cast<A>(C);  // Really, just call the casting operator, don't implicitly cast.

因为&#34;功能风格&#34;演员可以申请离婚(通过致电建设者),他们被认为是有害的。

没有错:

f(c1,c1)

获得A.人们通常不会将其视为“演员”。这通常意味着将这种类型的对象转换为该类型&#39;。

通常你不会写:

void A A(const&amp; C){...} // function

获取

d = A(c)

因为它令人困惑。 (是一个类还是一个函数?)

你不想写:

void A toA(const&amp; C){...}

只是因为这个功能最好封装在A类中。但它不是特别有害。