这是演员还是建筑?

发布于 2024-12-07 04:10:13 字数 471 浏览 0 评论 0原文

读完教科书上的一些内容后,我有点困惑。关于代码:

void doSomeWork(const Widget& w)
{
    //Fun stuff.
}

doSomeWork(Widget(15));

doSomeWork() 采用 const Widget& 参数。教科书《Effective C++ III》指出,这将创建一个临时 Widget 对象以传递给 doSomeWork。它说这可以替换为:

doSomeWork(static_cast<Widget>(15));

因为两个版本都是强制转换 - 第一个显然只是函数风格的 C 强制转换。我本以为 Widget(15) 会调用一个带有一个整数参数的小部件的构造函数。

在这种情况下构造函数会被执行吗?

I'm a little confused after reading something in a textbook. Regarding the code:

void doSomeWork(const Widget& w)
{
    //Fun stuff.
}

doSomeWork(Widget(15));

doSomeWork() takes a const Widget& parameter. The textbook, Effective C++ III, states that this creates a temporary Widget object to pass to doSomeWork. It says that this can be replaced by:

doSomeWork(static_cast<Widget>(15));

as both versions are casts - the first is just a function-style C cast apparently. I would have thought that Widget(15) would invoke a constructor for widget taking one integer parameter though.

Would the constructor be executed in this case?

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

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

发布评论

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

评论(7

空名 2024-12-14 04:10:13

在 C++ 中,这种表达式是强制转换的一种形式,至少在语法上是如此。即,您使用 C++ 函数转换语法 Widget(15) 来创建 Widget 类型的临时对象。

即使您使用多参数构造函数构造临时对象(如 Widget(1, 2, 3)),它仍然被视为函数转换表示法的变体(请参阅5.2.3)

换句话说,您的“这是强制转换还是构造”问题的表述不正确,因为它意味着强制转换和“构造”之间的相互排他性。它们并不相互排斥。事实上,每个类型转换(无论是显式强制转换还是更隐式的转换)无非是目标类型的新临时对象的创建(“构造”)(可能不包括某些引用初始化)。

顺便说一句,函数式转换表示法主要是 C++ 表示法。 C 语言没有函数式类型转换。

In C++ this kind of expression is a form of a cast, at least syntactically. I.e. you use a C++ functional cast syntax Widget(15) to create a temporary object of type Widget.

Even when you construct a temporary using a multi-argument constructor (as in Widget(1, 2, 3)) it is still considered a variation of functional cast notation (see 5.2.3)

In other words, your "Is this a cast or a construction" question is incorrectly stated, since it implies mutual exclusivity between casts and "constructions". They are not mutually exclusive. In fact, every type conversion (be that an explicit cast or something more implicit) is nothing else than a creation ("construction") of a new temporary object of the target type (excluding, maybe, some reference initializations).

BTW, functional cast notation is a chiefly C++ notation. C language has no functional-style casts.

白衬杉格子梦 2024-12-14 04:10:13

短:是的。

Long:

,例如:

#include <iostream>

struct W
{
    W( int i )
    {
        std::cout << "W(" << i << ")\n";
    }
};

int main(int argc, const char *argv[])
{
    W w(1);
    W(2);
    static_cast<W>(3);
}

你总是可以自己测试这些东西

W(1)
W(2)
W(3)

Short: Yes.

Long:

You can always test those things yourself, by doing e.g.:

#include <iostream>

struct W
{
    W( int i )
    {
        std::cout << "W(" << i << ")\n";
    }
};

int main(int argc, const char *argv[])
{
    W w(1);
    W(2);
    static_cast<W>(3);
}

which is outputting

W(1)
W(2)
W(3)
自控 2024-12-14 04:10:13

是的,两者都是:)。强制转换是一种语法结构(即您键入的内容)。在这种情况下,构造函数作为强制转换的结果而被调用。很像构造函数会因键入而被调用

Widget w(15);

Yes, it is both :). A cast is a syntactic construct (i.e. something you type). In this case, a constructor is invoked as a consequence of the cast. Much like a constructor would be invoked as a consequence of typing

Widget w(15);
淑女气质 2024-12-14 04:10:13

Widget(15)static_cast(15) 都是强制转换或转换
运营商,如果您愿意的话。两者都创建指定的新对象
类型,通过将 15 转换为 Widget。由于 15 没有任何
转换运算符,执行此转换的唯一方法是
分配必要的内存(在堆栈上)并调用
适当的构造函数。这实际上与 double(15) 没有什么不同
static_cast(15),只不过我们通常不会想到
double 具有构造函数(但生成的 double 是一个新的
对象,与 15 不同,后者的类型为 int)。

Both Widget(15) and static_cast<Widget>(15) are casts, or conversion
operators, if you prefer. Both create a new object of the designated
type, by converting 15 into a Widget. Since 15 doesn't have any
conversion operators, the only way to do this conversion is by
allocating the necessary memory (on the stack) and calling the
appropriate constructor. This is really no different that double(15)
and static_cast<double>(15), except that we usually don't think of
double as having a constructor (but the resulting double is a new
object, distinct from the 15, which has type int).

黑白记忆 2024-12-14 04:10:13

你说:

第一个显然只是函数式的 C 转换

第一个不会在 C 中编译,它不是 C 风格。 C 风格看起来像 (Widget)15。这里,使用 Widget::Widget(int) 创建临时对象。

因此,它不是C型演员。

You said:

the first is just a function-style C cast apparently

The first would not compile in C, it's not C-style. C-style looks like (Widget)15. Here, the temporary object is created, using Widget::Widget(int).

Therefore, it is not a C-style cast.

悍妇囚夫 2024-12-14 04:10:13

是的当然。任何采用单个参数的构造函数都将被视为转换构造函数。您的构造函数已经采用单个 int 参数,以便编译器可以“隐式”调用此构造函数来匹配参数(值为 15,即 int)。

有一个简单的技巧可以防止此类错误,只需在构造函数之前使用关键字 explicit 即可。

查看了解更多信息。

Yes, of course. Any constructor takes a single parameter would be considered as CONVERSION CONSTRUCTOR. Your constructor is already taking a single int parameter, so that the compiler can "implicitly" call this constructor to match the argument (with the value 15, which is int).

There is a simple trick to prevent such errors, just use the keyword explicit before your constructor.

Check this for more information.

过期情话 2024-12-14 04:10:13

是啊。您可以替换

Widget(15)

static_cast<Widget>(15)

因为它将被编译器替换回来 :D

当您将 int 转换为 Widget 时,编译器会查找 Widget::Widget(int);并将其放在那里。

Yeeeah. You can replace

Widget(15)

with

static_cast<Widget>(15)

Because it will be replaced back by compiler :D

When you cast int to Widget compiler looks for Widget::Widget(int); and place it there.

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