为什么不允许对一个临时对象进行非const引用,哪个函数getx()返回?显然,这是C++标准禁止的,但我对这种限制的目的感兴趣,而不是对标准的引用.
struct X
{
X& ref() { return *this; }
};
X getx() { return X();}
void g(X & x) {}
int f()
{
const X& x = getx(); // OK
X& x = getx(); // error
X& x = getx().ref(); // OK
g(getx()); //error
g(getx().ref()); //OK
return 0;
}
Run Code Online (Sandbox Code Playgroud)
ref()可以修改临时对象. ref()允许您欺骗编译器并获取此临时对象的链接,这解决了我们的问题.此外:
他们说"为const引用分配一个临时对象可以延长这个对象的生命周期","但是对于非const引用却没有任何说法".我的其他问题.以下赋值是否延长了临时对象的生命周期?
X& x = getx().ref(); // OK
Run Code Online (Sandbox Code Playgroud) 为什么这样:
#include <string>
#include <iostream>
using namespace std;
class Sandbox
{
public:
Sandbox(const string& n) : member(n) {}
const string& member;
};
int main()
{
Sandbox sandbox(string("four"));
cout << "The answer is: " << sandbox.member << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
给出输出:
答案是:
代替:
答案是:四
错误的形式:
int &z = 12;
Run Code Online (Sandbox Code Playgroud)
正确形式:
int y;
int &r = y;
Run Code Online (Sandbox Code Playgroud)
问题:
为什么第一个代码错了?标题中错误的"含义 "是什么?
允许这样做的背后的设计理由是什么?
const Foo& a = function_returning_Foo_by_value();
Run Code Online (Sandbox Code Playgroud)
但不是这个
Foo& a = function_returning_Foo_by_value();
Run Code Online (Sandbox Code Playgroud)
?
第二行可能出现什么问题(第一行不会出错)?
在以下代码行中:
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在调用者中手动构造和销毁对象.
所以我的问题是:
int x = 10;
int& y = x;
Run Code Online (Sandbox Code Playgroud)
为此,x在堆栈上分配为2/4/8字节,并将00 ... 1010写入这些字节.内存布局及其内容会是什么样的y?
出于某种原因,我无法找到这个确切的问题.为什么它被允许绑定rvalue到const lvalue reference,虽然如果没有它就不可能相同const?
我确实理解rvalue的生命周期以某种方式得到扩展(在第一种情况下),但如果是这样,为什么编译器不允许改变'rvalue',这不再是一个临时对象.
例如,请考虑以下代码:
int main(){
int &i=3; //produces error
const int&j =3; //compiles
return 1;
}
Run Code Online (Sandbox Code Playgroud) 作为作业的一部分,我们被要求创建一个 Vector3D 类,该类使用在堆上分配的内存。我有一个带有以下构造函数的 Vector3DHeap 类。
Vector3DHeap::Vector3DHeap(float& x, float& y, float& z)
{
this->x = &x;
this->y = &y;
this->z = &z;
}
Run Code Online (Sandbox Code Playgroud)
如果我想获得单位向量,我希望能够执行以下操作。这给出了错误消息“没有构造函数的实例与参数列表匹配,参数类型是(浮点数,浮点数,浮点数)。
Vector3DHeap* Vector3DHeap::getUnitVector()
{
float m = *getMagnitude();
return new Vector3DHeap((*x / m), (*y / m), (*z / m));
}
Run Code Online (Sandbox Code Playgroud)
如果我定义三个浮点变量 a、b 和 c 并将它们传递给构造函数,编译器会很高兴。上面的代码有什么问题?
Vector3DHeap* Vector3DHeap::getUnitVector()
{
float m = *getMagnitude();
float a, b, c;
a = *x / m;
b = *y / m;
c = *z / m;
return new Vector3DHeap(a, b, c);
}
Run Code Online (Sandbox Code Playgroud)
非常感谢,乔治
这是我的代码:
class Base
{
public:
virtual void show() const = 0;
};
class Child : public Base
{
private:
static const int i = 1;
public:
virtual void show() const
{
cout << i;
}
};
map<int, const Base &> myMap{
{ 0, Child() },
{ 1, Child() },
};
Base & b = Child();
int main()
{
b.show();
myMap.at(0).show(); // This provokes the error
system("pause>NUL");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我正在尝试使用global(或static)数据,这将调用某些virtual函数.当我在测试Base & b = …
我收到下一个错误,我找不到它的原因:
错误C2664'void SumID <long> :: operator()<int>(G&)':无法将参数1从'int'转换为'int&'
为什么通过引用传递int有问题?
我有下一堂课:
template <class T>
class SumID {
private:
T sumid;
public:
SumID():sumid()
{
}
SumID(T s)
{
sumid = s;
}
T getSumID()
{
cout << "inside getSum";
return sumid;
}
template <class G>
void operator() (G& a)
{
sumid = sumid+ a;
}
};
Run Code Online (Sandbox Code Playgroud)
我的主要:
SumID<long> s;
for (int i = 0; i < 5; i++)
s(5); // <-- error here
Run Code Online (Sandbox Code Playgroud) 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版本不会.)