STD :: BITSET ::参考对象在STD :: BITSET ::操作员[]中创建的寿命
Lifetime of std::bitset::reference object created in std::bitset::operator[]?
我一直在查看BITSET标准C 库标头的标头文件。我发现过载的运算符[] operator[](size_t ndx)
(bitset
类定义)返回类reference
的TEMPRORAY对象。
reference
operator[](size_t __position)
{ return reference(*this,__position); }
这个超载的操作员封装了一个位的概念。此类的一个实例是实际位的代理。它在
之类的表达式中很有用bitset<10> b;
b[2] = true;
reference
类已定义了重载的=
运算符成员函数,以便上述示例可以工作:
//For b[i] = __x;
reference&
operator=(bool __x)
{
if (__x)
*_M_wp |= _Base::_S_maskbit(_M_bpos);
else
*_M_wp &= ~_Base::_S_maskbit(_M_bpos);
return *this;
}
但是,我对此表达感到困惑:
if (b[2]) {
//Do something
}
b[2]
首先返回类reference
的临时对象,然后在该返回的临时对象上调用Overloaded Operator(operator bool() const
)将其转换为bool
数据类型。
// For __x = b[i];
operator bool() const
{ return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; }
如果在堆栈上创建了临时对象(具有自动存储类的对象),则调用另一个函数(operator bool() const
)不应破坏第一个函数调用返回的临时对象(reference
对象reference operator[](size_t __position)
返回)?
C和C 中临时对象的寿命是什么?
来自class.temporary#4,强调是我的。
实现引入具有非平凡构造函数的类的临时对象([class.ctor],[class.copy])时,应确保将构造函数称为临时对象。同样,应要求使用非平凡的破坏者([class.dtor])暂时命令驱动器。临时对象被破坏为评估全表达([Into.exection])(词法)包含创建点的最后一步。这是正确的一个例外。破坏临时对象的价值计算和副作用仅与全表达相关,而不与任何特定的子表达相关联。
该临时对象将在该给定表达式的最后一步被破坏。
实际上,C 依赖于此非常常见的表达可以正确工作:
int x = 0, y = 0, z = 0, t = 0;
int a = x + y + z + t;
因为x+y
是临时的,x+y+z
是另一个临时。
临时寿命将在类规则中缩短。
在三个上下文中,临时性在与全表达的末端不同的点上被摧毁。第一个上下文是调用默认构造函数来初始化不相应的初始化器([dcl.init])的数组的元素。第二个上下文是调用复制构造函数在复制整个数组时复制数组的元素([[Expr.prim.lambda],[class.copy])。无论哪种情况,如果构造函数都有一个或多个默认参数,则在构建下一个数组元素之前对默认参数中创建的每个临时性的破坏进行测序,如果有的话。
它将在类中延长遵循规则。
第三个上下文是当引用绑定到临时性时。116参考所绑定的临时性或临时是一个子对象的完整对象。:
一个临时对象绑定到函数调用中的参考参数([expr.call]),直到包含调用的全表达完成为止。
未延长函数返回语句([stmt.return])中返回值的临时绑定的寿命未扩展;临时性在返回语句中的全表达结束时被销毁。
临时绑定到新的initializer([expr.new])中的参考文献,直到完成包含新的initializer的全表达完成。
在此示例中可以看到第一个上下文:
struct bar {
bar() { std::cout << __func__ << 'n'; }
bar(const bar&) { std::cout << __func__ << "__n"; }
~bar() { std::cout << __func__ << 'n'; }
};
struct foo {
foo(const bar& b = bar()) { std::cout << __func__ << 'n'; }
};
int main() {
foo f[] = {foo(), foo()};
}
上面的程序应输出:
bar
foo
~bar
bar
foo
~bar
第二个上下文将添加到C 17中,此后此程序:
struct bar {
bar() { std::cout << __func__ << 'n'; }
bar(const bar&) { std::cout << __func__ << "__n"; }
~bar() { std::cout << __func__ << 'n'; }
};
struct foo {
foo() {}
foo(const foo&, const bar& b = bar()) { std::cout << __func__ << "__n"; }
};
struct foox {
foo f[2];
};
int main() {
foox fx;
foox yx = fx;
}
必须输出:
bar
foo__
~bar
bar
foo__
~bar
在第三个上下文中,您可以在此处找到答案,此处
if (b[2])
中的条件在内,包括 operator bool()
是一个表达式,临时性对于表达式的整个生命周期都是有效的。
- 如何打印大于"无符号长长"的"std::bitset"的十进制值?
- 关于 std::bitset 构造函数的几个问题?
- 如何以滑动窗口方式从 std::bitset 读取位并将它们转换为 int?
- 在哪里可以找到 std::bitset 的数据成员?
- 对于std::bitset,是否有一个ffs()等价物
- OMNeT++ cPacket as std::bitset 以应用 Reed-Solomon 编码
- 将字符数组转换为 std::string 以传递到 std::bitset seg 错误
- std::bitset 哈希函数算法
- 与STD :: BITSET的工会成员的结构填充
- 为什么 MSVC 在实现 std::bitset::count 时不使用 __popcnt?
- 如何在数字大于类型 size_t 的最大数量时使用 std::bitset
- 从STD :: BITSET ::操作员[]扣除模板
- 重载 std::bitset 的移位运算符
- 在编译时初始化 c++ std::bitset
- 为什么 std::bitset 只支持整型数据类型?为什么不支持浮点数?
- g++ 内存不足为 std::bitset 分配
- 使用 std::bitset 时程序崩溃,但仅在使用 VC 2015 编译时崩溃
- 使用std :: bitset进行双重表示
- STD :: BITSET ::参考对象在STD :: BITSET ::操作员[]中创建的寿命
- 改变std :: bitset中一系列位值的最有效方法