这个问题询问所有临时值是否都是右值.
答案是否定的,因为如果我们考虑这个表达式:
const int &ri = 2 + 3;
Run Code Online (Sandbox Code Playgroud)
那么,同样的临时(2 + 3)值(这里是一个右值)可以用作后续表达式中的左值:
const int *pi = &ri;
Run Code Online (Sandbox Code Playgroud)
所以这个临时不是(仅)一个右值.
然后逻辑语句temporary ==> rvalue是错误的.
但是,我们不能写
const int &ri = &(2 + 3); // illegal, 2 + 3 -> temporary -> rvalue
Run Code Online (Sandbox Code Playgroud)
要么
int *i = &4; // illegal, 4 is an rvalue (literal)
Run Code Online (Sandbox Code Playgroud)
要么
int foo();
int *i = &foo(); // illegal, foo() -> temporary -> rvalue
Run Code Online (Sandbox Code Playgroud)
因此我的问题是,我们可以在某个表达式中生成一个rvalue而不需要临时或文字吗?是rvalue ==> (temporary or literal)真的吗?
我正在编写一个使用共享指针来构建复杂节点结构的库.由于结构中可能存在循环,并且为了避免内存泄漏,我在构建结构时决定采用以下策略:每当我传递一个临时对象时,我都使用shared_ptr(获取所有权); 每当我通过左值时,我都会使用weak_ptr.根据我的分析和库接口的设计方式,这应该完全避免循环.
但是,我在使用函数重载时遇到问题,以了解参数是rvalue还是左值.这是我得到的错误的一个非常简单的例子:
#include <iostream>
#include <memory>
using namespace std;
class MyClass {
public:
int a;
// this class contains some pointers to the node structure
};
MyClass fun(MyClass &&x, MyClass &&y)
{
// should produce an object that has ownership of the two others
}
MyClass fun(MyClass x, MyClass y)
{
// should not take ownership, but just copy the pointer
}
int main()
{
MyClass x, y;
fun(x, y);
fun(MyClass(), MyClass());
}
Run Code Online (Sandbox Code Playgroud)
使用g ++ 4.8.2进行编译时出现以下错误:
example.cpp: In function …Run Code Online (Sandbox Code Playgroud) 码:
void test(int&& a)
{
a++;
std::cout << a << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
并执行:
test(0);
Run Code Online (Sandbox Code Playgroud)
为什么输出1?因为我认为0是右值,它无法改变.
class Vec3{
private:
float x, y, z;
public:
Vec3() = default;
Vec3(const float c) {x = c; y = c; z = c;}
static Vec3& normalize(Vec3& v) {/* normalize */ return v;}
};
Vec3 aaa = Vec3( 1.0f);
Vec3 bbb = Vec3::normalize( Vec3( 1.0f));
Vec3 ccc = Vec3::normalize( aaa);
Run Code Online (Sandbox Code Playgroud)
我想编写将向量作为参数的函数,对它们进行一些处理并将它们作为引用返回.
在上面的代码中bbb不会编译,因为它是对rvalue的非const引用.我不能使它成为const因为normalize需要修改对象.如果我使函数接受rvalue references(Vec3&& v)然后ccc不会编译因为aaa是左值.我可以在不写两个版本的情况下完成这项工作normalize吗?
(我对rvalue vs左值引用感到困惑,我不明白为什么a someFunc(const Vec3& v)会接受rvalues和lvalues,而非const版本不会.)
该ff()函数返回一个右值但是当我更改函数的返回值时const,它是否返回左值?为什么下面的输出改变其输出"lvalue reference"到"rvalue reference"当我改变 test ff() { }成const test ff() { }
#include <iostream>
using namespace std;
class test { };
void fun( const test& a)
{
cout << "lvalue reference"<<endl;
}
void fun( test&& a)
{
cout << "rvalue reference"<<endl;
}
const test ff() { } // <<---return value is const now
int main()
{
fun(ff());
}
Run Code Online (Sandbox Code Playgroud)
输出:
lvalue reference
Run Code Online (Sandbox Code Playgroud) How is it possible to have an lvalue reference refer to an lvalue reference returned from a function? Isn't the lvalue reference returned from that function actually an rvalue from the perspective of the caller? For example:
class Obj {};
Obj& refToRef(Obj& o) {
return o;
}
int main() {
Obj o;
Obj& o2 = refToRef(o);
}
Run Code Online (Sandbox Code Playgroud)
How is o2 (an lvalue reference) able to refer to what appears to be an rvalue?
我想从函数返回一个布尔值或成功/失败枚举,并通过引用修改参数。但是,我想在调用函数中构造一个引用,而不是复制该值。
我有一些容器(例如std :: queue类型的“ example_q”)。queue.front()将返回对存储在队列中的值的引用。我可以复制该引用(示例A),也可以复制该引用(示例B),从而允许该值保留在队列中,但可以在队列外使用。
一种)
int a = example_q.front();
Run Code Online (Sandbox Code Playgroud)
B)
int& b = example_q.front();
Run Code Online (Sandbox Code Playgroud)
使用此差异,我还可以返回排队的值:
一种)
int get_front()
{
int a = example_q.front();
return a;
}
Run Code Online (Sandbox Code Playgroud)
B)
int& get_front()
{
return example_q.front();
}
Run Code Online (Sandbox Code Playgroud)
使用选项“ B”,我可以避免不必要的复制,而无需通过std :: move()语义将数据移出队列。
我的问题是,我可以通过引用传递的参数来执行“ B”吗?我是否需要以某种方式使用std :: move()/ rvalues / &&&?
void get_front(int& int_ref)
{
// somehow don't copy the value into referenced int_ref, but construct
// a reference in the caller based on an input argument?
int_ref = example_q.front();
}
Run Code Online (Sandbox Code Playgroud)
这将解决的问题是使API与其他修改引用参数但返回成功/失败值的函数匹配,即:
if(q.get_front(referrence_magic_here))
{
...
} …Run Code Online (Sandbox Code Playgroud) 以下将不起作用:
std::array<int, 3> arr = {1, 2, 3};
int **ptr = &(arr.data());
Run Code Online (Sandbox Code Playgroud)
因为我会尝试获取右值的地址。我已经解决了它:
std::array<int, 3> arr = {1, 2, 3};
int *ptr = arr.data();
int **ptr2 = &ptr;
Run Code Online (Sandbox Code Playgroud)
这似乎工作得很好。
我知道您不能获取右值的地址,但为什么在这里如此对待它?是因为将创建一个临时文件arr.data(),然后将其分配给ptr我,我会尝试获取该临时文件的地址吗?
我想知道如何将恒定时间 (O(1)) 中的右值向量附加到另一个向量。我知道使用std::insertand 的方法std::move,但是有没有任何方法std::vector<T>&&可以std::vector<T>&在 O(1) 时间内将 a 添加到。
class A
{
public:
A()
{
cout << "A()" << endl;
}
A(const A&)
{
cout << "A(const A&)" << endl;
}
A(A&&)
{
cout << "A(A&&)" << endl;
}
A& operator=(const A&)
{
cout << "A(const A&)" << endl;
}
A& operator=(A&&)
{
cout << "A(const A&&)" << endl;
}
~A()
{
cout << "~A()" << endl;
}
};
A&& f_1()
{
A a;
return static_cast<A&&>(a);
}
A f_2()
{
A a;
return static_cast<A&&>(a);
}
int main()
{
cout …Run Code Online (Sandbox Code Playgroud)