标签: rvalue-reference

c ++ 11 emplace_back和push_back语法与struct

我正在使用MSVC,Visual Studio 2013.

假设我有一个结构:

struct my_pair {
    int foo, bar;
};
Run Code Online (Sandbox Code Playgroud)

我想有效地添加一堆这些,而不是创建一个临时的,然后丢弃它:

vector<my_pair> v;
v.push_back(41, 42); // does not work              [a]
v.push_back({41,42}); // works                     [b]
v.emplace_back(41,42); // does not work            [c]
v.emplace_back({41,42}); // does not work          [d]
v.emplace_back(my_pair{41,42}); //works            [e]
Run Code Online (Sandbox Code Playgroud)

现在,如果我将构造函数和复制构造函数添加到我的代码中:

my_pair(int foo_, int bar_) : foo(foo_), bar(bar_) 
{
    cout << "in cstor" << endl;
}
my_pair(const my_pair& copy) : foo(copy.foo), bar(copy.bar)
{
    cout << "in copy cstor" << endl;
}
Run Code Online (Sandbox Code Playgroud)

然后行为改变:

v.push_back(41, 42); // does not work                              [f]
v.push_back({41,42}); …
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference c++11

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

C++ 0x右值引用 - lvalues-rvalue绑定

这是C++ 0x右值引用和临时值的后续问题

在上一个问题中,我询问了这段代码应该如何工作:

void f(const std::string &); //less efficient
void f(std::string &&); //more efficient

void g(const char * arg)
{
    f(arg);
}
Run Code Online (Sandbox Code Playgroud)

由于隐式临时似乎应该调用移动重载,这种情况发生在GCC中,而不是MSVC(或MSVC的Intellisense中使用的EDG前端).

这段代码怎么样?

void f(std::string &&); //NB: No const string & overload supplied

void g1(const char * arg)
{
     f(arg);
}
void g2(const std::string & arg)
{
    f(arg);
}
Run Code Online (Sandbox Code Playgroud)

看来,基于我之前问题的答案,该函数g1是合法的(并且被GCC 4.3-4.5接受,但不被MSVC接受).但是,GCC和MSVC都拒绝,g2因为第13.3.3.1.4/3条禁止左值绑定到rvalue ref参数.我理解这背后的基本原理 - 在N2831"使用右值参考修复安全问题"中对此进行了解释.我也认为GCC可能正如该论文的作者所预期的那样实施该条款,因为GCC的原始补丁是由其中一位作者(Doug Gregor)撰写的.

但是,我不是很直观.对我来说,(a)a const string &在概念上更接近于string &&a const char *,而且(b)编译器可以创建一个临时字符串g2,就好像它是这样编写的:

void g2(const std::string & …
Run Code Online (Sandbox Code Playgroud)

c++ lvalue rvalue-reference c++11

16
推荐指数
1
解决办法
4252
查看次数

完美转发对象成员

假设我有两个structs:

struct X {};
struct Y { X x; }
Run Code Online (Sandbox Code Playgroud)

我有功能:

void f(X&);
void f(X&&);
Run Code Online (Sandbox Code Playgroud)

我怎样写一个函数g()是需要Y&Y&&只有完美的转发X&X&&f(),分别为:

template <typename T>
void g(T&& t) {
  if (is_lvalue_reference<T>::value) {
    f(t.x);
  } else {
    f(move(t.x));
  }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码说明了我的意图,但随着参数数量的增加,它的可扩展性不高.有没有办法让它完美转发并使其可扩展?

c++ rvalue-reference perfect-forwarding c++11

16
推荐指数
1
解决办法
888
查看次数

了解右值参考

我认为我对rvalue引用并不十分了解.为什么以下错误无法编译(VS2012)'foo' : cannot convert parameter 1 from 'int' to 'int &&'

void foo(int &&) {}
void bar(int &&x) { foo(x); };
Run Code Online (Sandbox Code Playgroud)

我会假设int &&从bar传递到foo时将保留该类型.为什么它会int在函数体内转换成一次?

我知道答案是使用std::forward:

void bar(int &&x) { foo(std::forward<int>(x)); }
Run Code Online (Sandbox Code Playgroud)

所以也许我只是没有清楚地掌握原因.(另外,为什么不std::move呢?)

c++ rvalue-reference c++11

16
推荐指数
3
解决办法
2858
查看次数

左值参考和右值参考之间的重载分辨率

#include <iostream>

using namespace std;

void func(int (&ref)[6]) { cout << "#1" << endl; }
void func(int * &&ref) { cout << "#2" << endl; }

int main()
{
  int arr[6];
  func(arr); // g++(5.4): ambiguous, clang++(3.8): #2, vc++(19.11): #1

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这两个函数都是完全匹配.以下是标准的引用:

标准转换序列S1是比标准转换序列S2更好的转换序列

...

S1和S2是引用绑定(8.5.3),并且都不引用没有ref-qualifier声明的非静态成员函数的隐式对象参数,S1将rvalue引用绑定到rvalue,S2绑定左值引用.

这不是意味着第二个更好吗?

更新:

一个相关的问题.以下代码是它的简化版本.

#include <iostream>

using namespace std;

void func(int *&) { cout << "#1" << endl; }
void func(int *&&) { cout << "#2" << endl; }

int main()
{
  int arr[6]; …
Run Code Online (Sandbox Code Playgroud)

c++ overloading rvalue-reference language-lawyer

16
推荐指数
1
解决办法
423
查看次数

是否可以获取“ this”指针的地址?

我读到这this是一个右值,我们无法通过应用来获取其地址&this

在我的代码中,我尝试使用的引用绑定this。我想知道哪种地址可以给this?还是都错了?

到底是this什么?左值,右值,关键字还是其他?

void MyString::test_this() const{
    std::cout << "this: " << this << std::endl;
    const MyString * const& this_ref = this;
    std::cout << "thie_ref: " << &this_ref << std::endl;
    const MyString * const&& this_right = this;
    std::cout << "thie_right: " << &this_right << std::endl;
}

//this: 00CFFC14
//thie_ref: 00CFFB14
//thie_right: 00CFFAFC
Run Code Online (Sandbox Code Playgroud)

c++ reference this rvalue rvalue-reference

16
推荐指数
3
解决办法
1083
查看次数

Lambda闭包左值可以作为右值参考参数传递

我发现lvaluelambda闭包始终可以作为rvalue函数参数传递。

请参见以下简单演示。

#include <iostream>
#include <functional>

using namespace std;

void foo(std::function<void()>&& t)
{
}

int main()
{
    // Case 1: passing a `lvalue` closure
    auto fn1 = []{};
    foo(fn1);                          // works

    // Case 2: passing a `lvalue` function object
    std::function<void()> fn2 = []{};
    foo(fn2);                          // compile error

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

情况2是标准行为(我只是std::function为了演示目的而使用a ,但是任何其他类型的行为都相同)。

案例1如何以及为什么起作用?fn1函数返回后关闭的状态是什么?

c++ lambda closures rvalue-reference c++14

16
推荐指数
3
解决办法
329
查看次数

重载R值引用和代码重复

考虑以下:

struct vec
{
    int v[3];

    vec() : v() {};
    vec(int x, int y, int z) : v{x,y,z} {};
    vec(const vec& that) = default;
    vec& operator=(const vec& that) = default;
    ~vec() = default;

    vec& operator+=(const vec& that)
    {
        v[0] += that.v[0];
        v[1] += that.v[1];
        v[2] += that.v[2];
        return *this;
    }
};

vec operator+(const vec& lhs, const vec& rhs)
{
    return vec(lhs.v[0] + rhs.v[0], lhs.v[1] + rhs.v[1], lhs.v[2] + rhs.v[2]);
}
vec&& operator+(vec&& lhs, const vec& rhs)
{
    return move(lhs += …
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference c++11

15
推荐指数
3
解决办法
4757
查看次数

关于如何识别Rvalue或Lvalue引用以及if-it-has-a-name规则

我正在阅读托马斯·贝克尔关于右值参考及其使用的文章.在那里,他定义了他称之为if-it-a-name规则:

声明为右值引用的事物可以是左值或右值.区别标准是:如果它有一个名字,那么它就是一个左值.否则,它是一个右值.

这对我来说听起来很合理.它还清楚地标识了右值参考的右值.

我的问题是:

  1. 你同意这个规则吗?如果没有,您能举例说明违反此规则吗?
  2. 如果没有违反此规则.我们可以使用此规则来定义表达式的rvalueness/lvaluness吗?

c++ rvalue lvalue rvalue-reference c++11

15
推荐指数
3
解决办法
2991
查看次数

C++,函数参数中的右值引用

我正在努力理解rvalue参考文献.我看到他们是如何在构造函数中使用,之类的东西std::movestd::forward,但我还是不明白为什么这不起作用:

void func(string&& str)
{
    cout << str << endl;
}
int main(int argc, char* argv[])
{
    string s("string");
    func(s);
}
Run Code Online (Sandbox Code Playgroud)

这样做:

template<typename T>
void func(T&& str)
{
    cout << str << endl;
}
int main(int argc, char* argv[])
{
    string s("string");
    func(s);
}
Run Code Online (Sandbox Code Playgroud)

为什么它与函数模板版本一起使用?

c++ templates rvalue-reference c++11

15
推荐指数
2
解决办法
2904
查看次数