为什么通过 const 引用传递临时值时会调用复制构造函数?

发布于 2024-10-12 21:43:11 字数 396 浏览 9 评论 0原文

我将一个未命名的临时对象传递给使用 const ref 参数定义的函数。该类的复制构造函数是私有的,我收到编译错误。我不明白为什么在这种情况下调用复制构造函数。

class A {
public:
  A(int i) {}
private:
  A(const A&) {}
};

void f(const A& a)
{
}

int main()
{
  f(A(1)); // <-- error here: 'A::A(const A&)' is private
}

正如预期的那样,当我将 main 更改为:

A a(1);
f(a);

它有效。

编辑:编译器是 gcc 4.1.2

I am passing an unnamed temporary object to a function defined with const ref parameter. The copy ctor of the class is private, and I get a compilation error. I don't understand why a copy constructor is called in this situation.

class A {
public:
  A(int i) {}
private:
  A(const A&) {}
};

void f(const A& a)
{
}

int main()
{
  f(A(1)); // <-- error here: 'A::A(const A&)' is private
}

As expected, when I change the main to:

A a(1);
f(a);

it works.

EDIT: the compiler is gcc 4.1.2

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

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

发布评论

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

评论(3

轮廓§ 2024-10-19 21:43:11

表达式 A(1) 是一个右值 5.2.3 [expr.type.conv]。

在使用作为右值的表达式初始化 const 引用(函数参数)时,编译器可能创建一个临时值并复制该值表达式到临时并将该引用绑定到该临时。 8.5.3 [dcl.init.ref] / 5。

[...] 无论复制是否实际完成,用于进行复制的构造函数都应该是可调用的。

请注意,此行为是由于下一版本的 C++ 中的更改所致。在新标准中,从类prvalue初始化的const引用必须直接绑定到引用对象;在这种情况下,不允许创建临时对象,并且不使用或不需要复制构造函数。

The expression A(1) is an rvalue 5.2.3 [expr.type.conv].

In initializing a const reference (the function argument) with an expression that is an rvalue the compiler may create a temporary and copy the value of that expression to the temporary and bind that reference to that temporary. 8.5.3 [dcl.init.ref] / 5.

[...] The constructor that would be used to make the copy shall be callable whether or not the copy is actually done.

Note that this behaviour is due to change in the next version of C++. In the new standard a const reference initialized from a class prvalue must be bound directly to the reference object; no temporary is permitted to be created in this case and a copy constructor is not used or required.

当梦初醒 2024-10-19 21:43:11

您可以在使用临时对象需要复制构造函数中找到问题的答案,或者直接访问 http://gcc.gnu.org/bugs/#cxx%5Frvalbind

C++ 标准表示临时
应该在 this 中创建对象
上下文及其内容充满了
我们正在尝试的对象的副本
绑定到引用;它还说
可以删除临时副本,
但语义限制(例如
复制构造函数的可访问性)
还需要检查。

欲了解更多信息,您可以
请参阅以下段落
C++ 标准:[dcl.init.ref]/5,
项目符号 2、子项目符号 1,以及
[类.临时]/2。

从 GCC 4.3.0 开始,GCC 不再
对于这种情况给出一个错误。这
改变是基于意图
C++语言委员会。截至
2010-05-28,最终草案
C++0x 标准允许这样做
代码没有错误。

You can find the answer to your question in Copy Constructor Needed with temp object or go directly to http://gcc.gnu.org/bugs/#cxx%5Frvalbind

The C++ Standard says that a temporary
object should be created in this
context and its contents filled with a
copy of the object we are trying to
bind to the reference; it also says
that the temporary copy can be elided,
but the semantic constraints (eg.
accessibility) of the copy constructor
still have to be checked.

For further information, you can
consult the following paragraphs of
the C++ standard: [dcl.init.ref]/5,
bullet 2, sub-bullet 1, and
[class.temporary]/2.

Starting with GCC 4.3.0, GCC no longer
gives an error for this case. This
change is based on the intent of the
C++ language committee. As of
2010-05-28, the final proposed draft
of the C++0x standard permits this
code without error.

仙气飘飘 2024-10-19 21:43:11

因为a(1)调用了构造函数A(int i),然后在调用void f(const A&)时又调用了A(const A&)。

使 A(int i) 构造函数显式化,您不应该遇到此错误。

编辑:我想我误解了这个问题。我可能会删除这个。

Because a(1) calls the constructor A(int i) and then A(const A&) is called in the call to void f(const A&).

Make the A(int i) constructor explicit and you should not face this error.

Edit: I think i misunderstood the question. I might delete this.

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