请参阅下面的代码段:
#include<vector>
using std::vector;
int main()
{
vector<int> a;
auto &&it=--a.end();//what?the hint tell me it deduces a lvalue reference type!
}
Run Code Online (Sandbox Code Playgroud)
我们都知道,当操作数本身是一个右值时,一个自定义的类operator --
返回一个xvalue--Myclass()
.显然Myclass()
是prvalue,所以返回值也--Myclass()
应该是rvalue(prcisely,xvalue).
来自cppref
am,对象表达式的成员,其中a是rvalue,m是非引用类型的非静态数据成员;
那么为什么auto
在这种情况下推导左值引用呢?更重要的是,可以编译代码片段而不会出现任何错误!
为什么rvalue可以绑定到左值参考?
而且我遇到了一个令人困惑的错误(与上面的代码片段不一样,我确定矢量不是空的):后来当我使用时it
, 发生了段故障!
导致段错误的代码(最后三行)这段代码是中文在线测试PAT的答案,当我提交答案时,会引起段错误.
是否使用左值引用绑定a 并在以后使用它是未定义的行为--Myclass()
?
我知道的一件事可能不是真的,那就是T
应该是可复制构造的,也就是说,T
应该有一个可访问的复制构造函数。
但是,是否还有其他要求,例如副本可分配?
作为补充,我记得Effective STL说vector<bool>
不是标准容器,因为它不满足T *p=&c[0]
格式良好的要求。
std::size_t
可以存储任何类型(包括数组)的理论上可能的对象的最大大小.
我知道确切的值是平台相关的.但是谁决定了theoretically possible object
编译器或操作系统,甚至计算机制造商的规模?可以计算理论上可能的对象的大小,还是仅仅由人为规则决定?
另外,如果机器是64位,这是否意味着最大对象大小可能是2 ^ 64字节?
这是代码示例:
#include<iostream>
using namespace std;
namespace B
{
int ohoh=2;
}
namespace A
{
int ohoh=666;
namespace C
{
//using B::ohoh;(as if declared by using directive) //why does the lookup not stops here?
int foo()
{
using namespace B;
cout<<ohoh<<endl;
}
}
}
int main()
{
A::C::foo();
}
Run Code Online (Sandbox Code Playgroud)
输出是666但不是2.为什么?
引自cppref
对于非限定名称,即名称不在范围解析运算符::右侧的名称,名称查找检查范围如下所述,直到它找到任何类型的至少一个声明,此时查找停止并且不会审查其他范围. (注意:从某些上下文中查找会跳过一些声明,例如,查找用于左侧的名称:忽略函数,变量和枚举器声明,查找用作基类说明符的名称会忽略所有非类型声明)
出于非限定名称查找的目的,using命令指定的命名空间中的所有声明都显示为在最近的封闭命名空间中声明,该命名空间直接或间接包含using-directive和指定命名空间.
从上面引用的段落中,名称查找应该停在最近的位置namespace C
,我在代码中注释了.为什么它不会停止并找到A::ohoh
?
顺便说一句,我认为我应该尽可能少地使用using指令.
在C++中,当对象的析构函数被调用时,它首先调用子类的析构函数,然后是父类的析构函数,这与构造过程相反。但为什么?这似乎是一个简单的问题,但我还没有在互联网上找到令人满意的答案。有人可以解释以这种顺序进行破坏的必要性吗?