相关疑难解决方法(0)

传值和后移是构建一个不好的习惯吗?

由于我们在C++中移动了语义,所以现在通常这样做

void set_a(A a) { _a = std::move(a); }
Run Code Online (Sandbox Code Playgroud)

原因是,如果a是左值,则副本将被删除,并且只有一个移动.

但如果a是左值,会发生什么?似乎将有一个复制结构,然后是一个移动赋值(假设A有一个适当的移动赋值运算符).如果对象具有太多成员变量,则移动分配可能成本很高.

另一方面,如果我们这样做

void set_a(const A& a) { _a = a; }
Run Code Online (Sandbox Code Playgroud)

只有一个副本分配.如果我们传递左值,我们可以说这种方式优于传值的习语吗?

c++ pass-by-value rvalue-reference move-semantics c++11

63
推荐指数
4
解决办法
1万
查看次数

通过值与引用或指针传递的性能成本?

让我们考虑一个对象foo(可能是一个int,一个double,一个习惯struct,一个class,等等).我的理解是,通过foo引用函数(或只是传递指针foo)来传递更高的性能,因为我们避免制作本地副本(如果foo很大则可能很昂贵).

但是,从这里的答案来看,似乎64位系统上的指针实际上可以预期大小为8字节,无论指向什么.在我的系统上,a float是4个字节.这是否意味着如果foo是类型float,那么仅通过值传递而不是给它指向它是更有效的foo(假设没有其他约束可以使得使用一个比函数内的另一个更有效)?

c++ pointers pass-by-reference pass-by-value pass-by-pointer

26
推荐指数
4
解决办法
2万
查看次数

何时重载通过引用(l值和r值)优先传递给值?

我已经看到它说一个operator=带有相同类型by-value的参数的文件在C++ 11中既作为复制赋值运算符又作为移动赋值运算符:

Foo& operator=(Foo f)
{
    swap(f);
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

替代方案的重复次数将超过两倍,并且可能出现错误:

Foo& operator=(const Foo& f)
{
    Foo f2(f);
    swap(f2);
    return *this;
}

Foo& operator=(Foo&& f)
{
    Foo f2(std::move(f));
    swap(f2);
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

在什么情况下,ref-to-const和r-value重载优先通过值,或何时需要?我正在考虑std::vector::push_back,例如,它被定义为两个重载:

void push_back (const value_type& val);
void push_back (value_type&& val);
Run Code Online (Sandbox Code Playgroud)

在第一个示例中,pass by value 用作复制赋值运算符和移动赋值运算符,无法push_back在Standard中定义为单个函数?

void push_back (value_type val);
Run Code Online (Sandbox Code Playgroud)

c++ overloading assignment-operator copy-and-swap c++11

24
推荐指数
1
解决办法
1945
查看次数

在重载函数的函数参数中使用rvalue引用会创建太多组合

想象一下,你有很多重载的方法(在C++ 11之前)看起来像这样:

class MyClass {
public:
   void f(const MyBigType& a, int id);
   void f(const MyBigType& a, string name);
   void f(const MyBigType& a, int b, int c, int d);
   // ...
};
Run Code Online (Sandbox Code Playgroud)

这个函数复制了a(MyBigType),所以我想通过提供一个版本f来移动a而不是复制它来添加优化.

我的问题是,现在f重载次数将重复:

class MyClass {
public:
   void f(const MyBigType& a, int id);
   void f(const MyBigType& a, string name);
   void f(const MyBigType& a, int b, int c, int d);
   // ...
   void f(MyBigType&& a, int id);
   void f(MyBigType&& a, string …
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference c++11

19
推荐指数
3
解决办法
1855
查看次数

在C++中将通用构造函数赋给成员变量时,std :: move或std :: forward

考虑以下类foo1foo2

template <typename T>
struct foo1
{
    T t_;

    foo1(T&& t) :
        t_{ std::move(t) }
    {
    }
};

template <typename T>
struct foo2
{
    foo1<T> t_;

    foo2(T&& t) :
        t_{ std::forward<T>(t) }
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

始终是构造函数foo1表示初始化成员变量的正确方法T吗?即通过使用std::move.

总是这样的构造函数foo2表示foo1<T>由于需要转发到foo1的构造函数而初始化成员变量的正确方法吗?即通过使用std::forward.

更新

以下示例无法foo1使用std::move:

template <typename T>
foo1<T> make_foo1(T&& t)
{
    return{ std::forward<T>(t) };
}

struct bah {};

int main()
{
    bah b;

    make_foo1(b); // compiler …
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics perfect-forwarding c++11 c++14

10
推荐指数
1
解决办法
951
查看次数

std :: move与编译器优化

例如:

void f(T&& t); // probably making a copy of t

void g() 
{
    T t;
    // do something with t
    f(std::move(t));
    // probably something else not using "t"
}
Run Code Online (Sandbox Code Playgroud)

void f(T const& t)在这种情况下是等效的,因为任何好的编译器都会产生相同的代码?如果这很重要,我对> = VC10和> = GCC 4.6感兴趣.

编辑:

根据答案,我想详细说明一下这个问题:

比较rvalue-referencepass-by-value方法,它是很容易忘记用std::movepass-by-value.编译器是否仍然可以检查是否不再对变量进行更改并消除不必要的副本?

rvalue-reference例如f(T()),方法仅使优化版本"隐式",并且要求用户明确指定其他情况,如果用户未完成实例f(std::move(t)),则明确地制作副本.那么,在这种优化相关的光中,方法被认为是好的吗?f(T(t));trvalue-reference

c++ compiler-optimization move-semantics

5
推荐指数
1
解决办法
966
查看次数

为什么std :: function模板构造函数不使用通用引用?

我认为具有通用引用参数的构造函数比没有引用的构造函数具有更好的性能。

From cppreference (https://en.cppreference.com/w/cpp/utility/functional/function/function), we can see that the template constructor for std::function is not using reference.

template< class F > function( F f );
Run Code Online (Sandbox Code Playgroud)

Is it a mistake? If not, why the standard doesn't requires the constructor use universal reference?

EDIT:

Let's think about two cases.

  1. F is a built-in type, here a function pointer whose size is 4 bytes.

Using universal reference:

lvalue case: 4 bytes are copied.

rvalue case: 4 bytes are copied. (Will you …

c++ c++11

3
推荐指数
1
解决办法
89
查看次数