标签: rvalue-reference

在重载函数的函数参数中使用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++"从容器中移出"

在C++ 11中,std::move当我们想要将值移动(破坏性地复制)到容器中时,我们可以提高效率:

SomeExpensiveType x = /* ... */;
vec.push_back(std::move(x));
Run Code Online (Sandbox Code Playgroud)

但我找不到任何其他方式.我的意思是这样的:

SomeExpensiveType x = vec.back(); // copy!
vec.pop_back(); // argh
Run Code Online (Sandbox Code Playgroud)

这在适配器上更常见(copy-pop)stack.可能存在这样的事情:

SomeExpensiveType x = vec.move_back(); // move and pop
Run Code Online (Sandbox Code Playgroud)

为了避免副本?这已经存在了吗?我在n3000中找不到类似的东西.

我有一种感觉,我错过了一些非常明显的东西(比如它的不必要),所以我准备好了"ru dum".:3

c++ containers rvalue-reference c++11

18
推荐指数
1
解决办法
3281
查看次数

可以将std :: function从rvalue引用移动构造到临时的functor对象吗?

我有一个untemplated仿函数对象,我试图存储为std::function另一个对象内部.这个对象非常重量级,因此它被标记为不可复制,但它确实有一个移动构造函数.但是,尝试从临时构造函数构造std :: function或分配它失败.

这是引发错误的最小示例.

// pretend this is a really heavyweight functor that can't be copied.
struct ExampleTest
{
    int x;
    int operator()(void) const {return x*2;}
    ExampleTest(  ) :x(0){}
    ExampleTest( int a ) :x(a){}

    // allow move
    ExampleTest( ExampleTest &&other ) :x(other.x) {};

private: // disallow copy, assignment
    ExampleTest( const ExampleTest &other );
    void operator=( const ExampleTest &other );
};

// this sometimes stores really big functors and other times stores tiny lambdas.
struct ExampleContainer
{
    ExampleContainer( int …
Run Code Online (Sandbox Code Playgroud)

c++ std rvalue-reference c++11

18
推荐指数
1
解决办法
2627
查看次数

可以使用不正确的签名将C++ 11 lambda分配给std :: function

以下编译和运行(在Apple LLVM版本6.1.0和Visual C++ 2015下):

#include <functional>
#include <iostream>

struct s { int x; };

int main(int argc, char **argv)
{
    std::function<void (s &&)> f = [](const s &p) { std::cout << p.x; };
    f(s {1});
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么分配不会std::function<void (s &&)> f = [](const s &p) { std::cout << p.x; };产生错误?接受右值引用的函数不应该与接受const左值引用的函数具有相同的签名,如果它?const从lambda声明中删除确实会产生预期的错误.

c++ lambda rvalue-reference c++11

18
推荐指数
2
解决办法
1219
查看次数

字面数字是否可变?

当然,这不会编译:

int &z = 3; // error: invalid initialization of non-const reference ....
Run Code Online (Sandbox Code Playgroud)

这将编译:

const int &z = 3; // OK
Run Code Online (Sandbox Code Playgroud)

现在,考虑一下:

const int y = 3;
int && yrr = y; // const error (as you would expect)
int && yrr = move(y); // const error (as you would expect)
Run Code Online (Sandbox Code Playgroud)

这些下一行确实为我编译.我认为不应该.

int && w = 3;
int && yrr = move(3);
void bar(int && x) {x = 10;}
bar(3);
Run Code Online (Sandbox Code Playgroud)

最后两行不会允许文字3被修改吗?3与const int有什么区别?最后,"修改"文字是否有任何危险?

(g ++ - 4.6(GCC)4.6.2 with …

c++ const rvalue-reference c++11

17
推荐指数
1
解决办法
258
查看次数

我应该返回一个右值引用(通过std :: move'ing)吗?

一篇C++ Next博客文章

A compute(…)
{
    A v;
    …
    return v;
}
Run Code Online (Sandbox Code Playgroud)

如果A具有可访问的副本或移动构造函数,则编译器可以选择忽略该副本.否则,如果A有移动构造函数,v则移动.否则,如果A有复制构造函数,v则复制.否则,将发出编译时错误.

我以为我应该总是返回值,std::move 因为编译器能够找出用户的最佳选择.但另一个例子来自博客文章

Matrix operator+(Matrix&& temp, Matrix&& y)
  { temp += y; return std::move(temp); }
Run Code Online (Sandbox Code Playgroud)

std::move是必要的,因为y必须将其视为函数内的左值.

啊,在研究这篇博文之后,我的脑袋几乎爆炸了.我尽力去理解推理,但是我学的越多,我就越困惑.我们为什么要借助于这个价值来回报这个价值std::move

c++ return rvalue-reference stdmove

17
推荐指数
3
解决办法
9073
查看次数

Lvalue到rvalue引用绑定

编译器一直在抱怨我试图将左值绑定到右值引用,但我看不出如何.我是C++ 11的新手,移动语义等,所以请耐心等待.

我有这个功能:

template <typename Key, typename Value, typename HashFunction, typename Equals>
Value& FastHash<Key, Value, HashFunction, Equals>::operator[](Key&& key)
{
    //  Some code here...

    Insert(key, Value()); // Compiler error here

    //   More code here.
}
Run Code Online (Sandbox Code Playgroud)

它调用这个方法:

template <typename Key, typename Value, typename HashFunction, typename Equals>
void FastHash<Key, Value, HashFunction, Equals>::Insert(Key&& key, Value&& value)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

我不断收到如下错误:

cannot convert argument 1 from 'std::string' to 'std::string &&'
Run Code Online (Sandbox Code Playgroud)

在Insert()调用上.是不是key在运算符重载中定义为右值?为什么它被重新解释为左值?

谢谢.

c++ rvalue-reference move-semantics c++11

17
推荐指数
1
解决办法
2万
查看次数

为什么要通过rvalue引用和值来获取std :: initializer_list?

std::initializer_list我所看到的大多数C++ 11代码都是按值来获取的,但有时它是由右值引用获取的.这样做有什么好的理由吗?

例如,我遇到的几乎所有例子都是这样的:

class A {
  public:
  A(std::initializer_list<int>);
};
Run Code Online (Sandbox Code Playgroud)

但我偶尔会看到这件事:

class B {
  public:
  B(std::initializer_list<int> &&);
};
Run Code Online (Sandbox Code Playgroud)

我理解一般的rvalue引用的用途和目的,但为什么在a的情况下,其中一个优先于另一个std::initializer_list?我唯一能想到的是class A允许初始化列表单独构建,并class B防止这种情况发生.

std::initializer_list<int> values {1,2,3,4};
A a(values); // valid
B b(values); // error
Run Code Online (Sandbox Code Playgroud)

但我想不出一个很好的理由,为什么要防止这是一件令人满意的事情.

那么,为什么会std::initializer_list采用右值参考而不是值?

c++ initializer-list rvalue-reference c++11

17
推荐指数
1
解决办法
1665
查看次数

为什么"decltype(i + j)"的结果不是右值参考?

我试图给出一个导致rvalue的操作的简单示例.

这个测试用例应该有效,但令人惊讶的是(对我而言),添加两个ints 的结果不是rvalue(引用).我在这里错过了什么?

void test(int i, int j)
{
    // this assert should pass, but fails:
    static_assert(std::is_same<decltype(i + j), int&&>(), "i + j should be a rvalue"); 
    // this assert passed, but should fail:
    static_assert(std::is_same<decltype(i + j), int>(), "this assert should fail...");
}
Run Code Online (Sandbox Code Playgroud)

c++ rvalue decltype rvalue-reference c++11

17
推荐指数
2
解决办法
5292
查看次数

普通右值引用和std :: forward返回的引用之间有什么区别?

我不能这样做:

int &&q = 7;
int &&r = q; 
//Error Message:
//cannot convert from 'int' to 'int &&'
//You cannot bind an lvalue to an rvalue reference
Run Code Online (Sandbox Code Playgroud)

如果我理解正确,在初始化右值引用时,也会初始化一个临时变量.所以int &&q = 7;可以认为是:

int temp = 7;
int &&q = temp;
Run Code Online (Sandbox Code Playgroud)

当在右侧使用参考时,我实际上是在使用裁判.所以int &&r = q;可以认为是:

int &&r = temp;  //bind an lvalue to an rvalue reference, cause error, understandable
Run Code Online (Sandbox Code Playgroud)

所以上面是我理解编译器错误发生的方式.


为什么添加std::forward可以解决?

int &&q = 7;
int &&r = std::forward<int>(q);
Run Code Online (Sandbox Code Playgroud)

我知道std::forward总是返回一个右值引用,引用的引用是如何std::forward不同的int&&q

c++ rvalue-reference c++11 value-categories

17
推荐指数
2
解决办法
652
查看次数