在以下代码行中:
bootrec_reset(File(path, size, off), blksize);
Run Code Online (Sandbox Code Playgroud)
用原型调用函数:
static void bootrec_reset(File &file, ssize_t blksize);
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
libcpfs/mkfs.cc:99:53:错误:从'File'类型的右值开始无效初始化'File&'类型的非const引用
libcpfs/mkfs.cc:30:13:错误:传递'void bootrec_reset(File&,ssize_t)'的参数1
我知道你不能const &根据标准将非const引用()传递给rvalues.但是,MSVC允许您这样做(请参阅此问题).这个问题试图解释为什么,但答案没有意义,因为他正在使用文字的引用,这是一个极端的案例,显然应该被禁止.
在给定的示例中,可以清楚地看到将发生以下事件顺序(就像在MSVC中一样):
File的构造函数将被调用.File,和blksize,被推入堆栈.bootrec_reset利用file.bootrec_reset,临时File被摧毁.有必要指出File引用需要是非const的,因为它是文件的临时句柄,在其上调用非const方法.此外,我不想将File构造函数参数传递bootrec_reset给那里构造,也没有任何理由File在调用者中手动构造和销毁对象.
所以我的问题是:
众所周知,在大多数情况下,T&&意味着"这是一个临时对象".但是,如果想要从函数返回临时对象,他/她可以按如下方式声明函数:
template<class T>
T f()
{
T t;
......
return t;
}
Run Code Online (Sandbox Code Playgroud)
或(注意:不正确)
template<class T>
T&& f()
{
T t;
......
return t;
}
Run Code Online (Sandbox Code Playgroud)
但我认为后者是过度的,因为前者足够向后兼容.
然而,我也发现它std::forward()的返回类型被声明为T &&,所以我确信我对此的理解是不完整的.
我真正的问题是:我们何时何地将函数的返回类型声明为T &&?
我尝试A按如下方式定义一个类:
template< typename T >
class A
{
public:
A( T elem )
: _elem( elem )
{}
private:
TYPE _elem; // "TYPE" should be either "T" in case "elem" is an r-value or "T&" in case "elem" is an l-value.
};
Run Code Online (Sandbox Code Playgroud)
在这里,我希望_elem有一个类型T,以防构造函数的参数elem是一个r值或者T&case中的类型elem是一个l值.
有谁知道这是如何实现的?
#include <vector>
using namespace std;
struct A
{
vector<int> coll;
};
void f(const vector<int>&){}
void f(vector<int>&&){}
int main()
{
f(A().coll); // Is "A().coll" an xvalue?
}
Run Code Online (Sandbox Code Playgroud)
C++ 11保证f(A().coll)会打电话void f(vector<int>&&)吗?
可能重复:
T &&在C++ 0x中意味着什么?
在我读到这个答案之前,我从未见过双安瓿.
有问题的代码段是这样的:
template <typename T>
T& as_lvalue(T&& x)
{
return x;
}
Run Code Online (Sandbox Code Playgroud)
有什么作用&&?可以传递什么类型的参数as_lvalue()
下面的代码编译并运行得很好.正当我以为我开始对rvalue引用和std :: forward进行了很好的掌握 - 这个非常简单的代码揭示了rvalue有一些非常基本的东西,我不明白.请澄清.
#include <iostream>
#include <iomanip>
using namespace std;
void fn( int&& n )
{
cout << "n=" << n << endl;
n = 43;
cout << "n=" << n << endl;
}
int main( )
{
fn( 42 );
}
Run Code Online (Sandbox Code Playgroud)
我用g ++ 4.7使用以下命令行编译它:
g ++ --std = c ++ 11 test.cpp
输出为:
n = 42
n = 43
我的主要问题是编译器在函数fn中存储'n'的位置?
我用GCC,Clang,ICC和VS测试了以下代码:
void f() {}
void g(void (&&)()) { }
int main() {
g(f);
}
Run Code Online (Sandbox Code Playgroud)
正如我们所看到的,g采用右值引用但是f是左值,并且通常,右值引用不能绑定到左值.这正是ICC抱怨的:
error: an rvalue reference cannot be bound to an lvalue
Run Code Online (Sandbox Code Playgroud)
VS也会出错,但出于另一个原因:
error C2664: 'void h(void (__cdecl &&)(void))' : cannot convert parameter 1 from 'void (__cdecl *)(void)' to 'void (__cdecl &&)(void)'
Run Code Online (Sandbox Code Playgroud)
这告诉我VS立即执行函数到指针的转换,而不是直接绑定引用f.值得一提的是,如果我替换g(f)为g(&f)那么四个编译器会产生同样的错误.
最后,GCC和Clang接受了代码,我相信它们是正确的.我的推理基于8.5.3/5
对类型"cv1 T1"的引用由类型"cv2 T2"的表达式初始化为
- 如果参考是左值参考[...]
- 否则,[...] 参考应为右值参考.
- 如果初始化表达式是 [...] 函数左值 [...]
然后 …
考虑:
void g(int&);
void g(int&&);
template<class T>
void f(T&& x)
{
g(std::forward<T>(x));
}
int main()
{
f(10);
}
Run Code Online (Sandbox Code Playgroud)
由于id-expression x是一个左值,并且std::forward对于左值和右值有重载,为什么调用不能绑定到std::forward需要左值的重载?
template<class T>
constexpr T&& forward(std::remove_reference_t<T>& t) noexcept;
Run Code Online (Sandbox Code Playgroud) 我想说明我的类的构造函数A将取得传递Data参数的所有权.显而易见的事情是采用一个unique_ptr值:
class A
{
public:
A(std::unique_ptr<Data> data) : _data(std::move(data)) { }
std::unique_ptr<Data> _data;
};
Run Code Online (Sandbox Code Playgroud)
但是,对于我的用例,没有理由为什么Data应该是指针,因为值类型就足够了.我能想到的唯一剩下的选项,以使真正明确表示Data会为所拥有的A是路过的右值引用:
class A
{
public:
A(Data&& data) : _data(std::move(data)) { }
Data _data;
};
Run Code Online (Sandbox Code Playgroud)
这是一种表明所有权的有效方式,还是有更好的方法可以不使用unique_ptr?
例子:
typedef enum Color
{
RED,
GREEN,
BLUE
} Color;
void func(unsigned int& num)
{
num++;
}
int main()
{
Color clr = RED;
func(clr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译时出现以下错误:
<source>: In function 'int main()':
<source>:16:9: error: cannot bind non-const lvalue reference of type 'unsigned int&' to an rvalue of type 'unsigned int'
func(clr);
^~~
Run Code Online (Sandbox Code Playgroud)
我认为clr我传递给的变量 ( )func(unsigned int&)是一个左值。我可以获得的地址clr并可以为其分配另一个值。当我尝试将它传递给 时,为什么它会变成右值func(unsigned int&)?
c++ ×10
rvalue-reference ×10
c++11 ×9
lvalue ×2
rvalue ×2
function ×1
gcc ×1
reference ×1
return-type ×1
templates ×1
temporary ×1
unique-ptr ×1