将值或引用传递给需要存储副本的C ++构造函数? [英] Pass by value or reference, to a C++ constructor that needs to store a copy?

查看:175
本文介绍了将值或引用传递给需要存储副本的C ++构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果一个C ++(隐式或显式)值构造函数需要通过value或reference-to-const接受它的参数,当它需要以它的方式在它的对象中存储一个参数的副本吗?

Should a C++ (implicit or explicit) value constructor accept its parameter(s) by value or reference-to-const, when it needs to store a copy of the argument(s) in its object either way?

这是我能想到的最短的例子:

Here is the shortest example I can think of:

struct foo {
    bar _b;
    foo(bar [const&] b) // pass by value or reference-to-const?
        : _b(b) { }
};

这里的想法是,当foo对象被创建时,我想最小化对bar的拷贝构造函数的调用

The idea here is that I want to minimize the calls to bar's copy constructor when a foo object is created, in any of the various ways in which a foo object might get created.

请注意,我确实知道一些关于复制elision和(Named)的返回值优化,我已阅读想要速度?按值传递,但我不认为这篇文章直接针对这个用例。

Please note that I do know a little bit about copy elision and (Named) Return Value Optimization, and I have read "Want Speed? Pass by Value", however I don't think the article directly addresses this use case.

修改:我应该更具体。

假设我不知道 sizeof(bar),或者是否 bar 是一个基本的内置类型( bar 可能是一个模板参数, foo 可以是类模板而不是类)。此外,不要假设 foo 的构造函数可以内联(或 bar ') 。假设我至少可能使用一个实现RVO的编译器。

Assume that I can't know the sizeof(bar), or whether or not bar is a fundamental, built-in type (bar may be a template parameter, and foo may be a class template instead of a class). Also, don't assume that foo's constructor can be inlined (or bar's, for that matter). Do assume that I at least might be using a compiler that implements RVO.

我想要的是有一个可能性(给编译器优化)这将调用 bar 的任何复制构造函数(即使在<$ c中执行 _b(b) $ c> foo 的初始化列表):

What I would like is for there to be a possibility (given compiler optimizations) that a call like this will invoke no calls to bar's copy constructor whatsoever (even when executing _b(b) in foo's initialization list):

foo f = function_that_creates_and_returns_a_bar_object_using_rvo();

这是可能的(给定C ++ 98标准)因此,如果 foo 通过引用到const而不是通过值接受其参数,那么它是否可能工作?

Is there any possibility (given the C++98 standard) that this can be done, and if so, is it more or less likely to work if foo accepts its parameter by reference-to-const instead of by value?

推荐答案

在C ++ 98和C ++ 03中,应该传递 const& bar ,然后复制。在C ++ 0x,你应该传递 bar 然后做一个移动(提供 bar 有一个移动构造函数)。

In C++98 and C++03, you should pass const& bar and then copy. In C++0x, you should pass bar and then do a move (provided bar has a move constructor).

#include <utility>

struct foo
{
    bar _b;

    foo(bar b) : _b(std::move(b)) {}
};

如果使用lvalue参数构造foo,将调用复制构造函数以创建 b ,并将该副本移动到 _b 。如果你用一个右值参数构造foo, bar 的move构造函数将被调用来移动到 b 它将再次移动到 _b

If you construct foo with an lvalue parameter, the copy constructor will be called to create a copy b, and that copy will be moved into _b. If you construct foo with an rvalue parameter, bar's move constructor will be called to move into b, and then it will be moved again into _b.

这篇关于将值或引用传递给需要存储副本的C ++构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆