如果临时性是隐含的不可修改的,这是如何工作的
If temporaries are implicitly non-modifiable, how does this work?
有人告诉我,在C++03中,临时变量是不可修改的。
然而,以下是在GCC 4.3.4上为我编译的(在C++03模式下):
cout << static_cast<stringstream&>(stringstream() << 3).str();
这是如何编译的?
(我不是在谈论与引用绑定的临时规则。)
有人告诉我,在C++03中,临时变量是不可修改的。
这是不对的。在其他情况下,临时值是通过评估右值创建的,既有非常量右值,也有常量右值。表达式的值类别和它所表示的对象的常量大多是正交的1。观察:
std::string foo();
const std::string bar();
给定上述函数声明,表达式foo()
是一个非常值,其求值将创建一个非常临时值,而bar()
是一个创建非常临时值的非常值。
请注意,您可以在非常值上调用任何成员函数,允许您修改对象:
foo().append(" was created by foo") // okay, modifying a non-const temporary
bar().append(" was created by bar") // error, modifying a const temporary
由于operator=
是一个成员函数,您甚至可以为非常量值赋值:
std::string("hello") = "world";
这应该是足够的证据来说服您临时性是而不是隐式常量。
1:标量右值是一个例外,例如42。他们总是非常惊讶
首先,"修改临时"answers"通过右值修改对象"是有区别的。我会考虑后者,因为前者对讨论没有实际用处[1]。
我在3.10/10
(C++11中的3.10/5
)中发现了以下内容:
对象的左值是必需的为了修改对象类类型的右值也可以用于在下修改其引用某些情况。[示例:a为对象调用的成员函数(9.3)可以修改对象。]
因此,右值本身不是const
,但它们在除某些特定情况外的所有情况下都是不可修改的。
然而,在我看来,成员函数调用可以修改右值似乎表明,通过右值修改对象的绝大多数情况都得到了满足。
特别是,断言(在我链接的原始问题中)(obj1+obj2).show()
对非const
show()
[呃,为什么?!]是错误的。
因此,答案是(稍微改变结论的问题措辞),通过成员函数访问的右值本质上是不可修改的。
[1] -值得注意的是,如果你可以从原始右值中获得临时的左值,你可以用它做任何你喜欢的事情:
#include <cstring>
struct standard_layout {
standard_layout();
int i;
};
standard_layout* global;
standard_layout::standard_layout()
{
global = this;
}
void modifying_an_object_through_lvalue(standard_layout&&)
{
// Modifying through an *lvalue* here!
std::memset(global, 0, sizeof(standard_layout));
}
int main()
{
// we pass a temporary, but we only modify it through
// an lvalue, which is fine
modifying_an_object_through_lvalue(standard_layout{});
}
(感谢Luc Danton的代码!)
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 链表c++插入,所有情况都已检查,但没有任何工作
- 当 int 方法工作正常时,void 方法有何不同,或者为什么我不能调用 void 方法?