c++ - 右值需要分配哪些向后兼容性?
问题描述
C++ 入门 5:
(代码也来自本书,此处提供了 99% 的上下文)
#include <string>
using namespace std;
int main()
{
//no error
string s1 = "123", s2 = "aaaa";
s1 + s2 = "wow";
auto a = (s1 + s2).find("a");
}
在新标准之前(这里是 C++11),没有办法阻止这种用法。为了保持向后兼容性,库类继续允许分配给右值,但是,我们可能希望在我们自己的类中防止这种用法。在这种情况下,我们希望将左侧操作数(即
this
指向的对象)强制为左值。
右值需要分配哪些向后兼容性?
顺便说一句,我也很好奇为什么s1 + s2 = "wow"
允许但int i = 3, j = 4; i + j = 7;
不允许。(由于密切相关,我选择不打开另一个问题)
解决方案
这可能是一个反气候的猜测。我会欢迎任何其他具体示例,但是遵循一般规则似乎非常合理。
这种限制不会破坏任何特定的代码,但会限制接受程序的域。当涉及到这样的变化时,c++ 是相当保守的,有时会非常痛苦。一个值得注意的例子是最令人烦恼的解析,如果
A a();
被解释为默认构造的代码会破坏什么A
?然而,它不能以这种方式向后兼容 c 语法。那是一个相当用于语法分析的 PIA。c++ 允许对用户定义类型的运算符含义进行语义重新定义。我不知道是否有语义重定义的好例子,
operator=
但是对于其他运算符有一些相当值得注意的例子。 boost::program_optionsoperator()
以一种非常奇怪的方式“滥用”,以创建简洁的语法,并且Eigen 重新定义了逗号运算符语义。指向成员的操作符经常被重新定义来做一些非标准的事情,因为它们在默认情况下并不经常使用。所以有时它很有用。我想它可能对
operator=
具有副作用的类有用,并且不一定要更改内存中的值。我想在某些嵌入式开发中,您可以拥有Row
并且Col
您可以编写row * col = LED_ON
或类似的东西。我脑海中的另一个例子是表达式库,例如,还没有operator<=>
,所以operator=
可以在它的地方使用来评估像(p ^ p) <=> p
.
operator=
在运算符中没有什么特别之处,并且它们并不比其他成员函数特别。如果你写这样的代码:
#include <iostream>
using namespace std;
struct A{
friend ostream& operator<<(ostream& out, A& a) { out << "A "; return out;}
};
int main() {
A a1, a2;
cout << a1=a2 << '\n';
return 0;
}
它会……破裂。那是因为按位移位优先于=
. 它需要在 . 周围加上括号a1=a2
。这是为了说明operator=
在语言中确实没有特殊权利的观点。
另一件事是您几乎可以随心所欲地重载这些运算符,因此编写
#include <iostream>
using namespace std;
struct A{
bool operator=(A& rhs) {return true;}
};
int main() {
A a1, a2;
cout << (a1=a2) << '\n';
return 0;
}
是完全合法的。语言为操作员提供了句法快捷方式,仅此而已。我认为很多人抱怨(a+b).method()
有效,这对于(a+b).operator=()
.
奖励:带有int
s 的示例不起作用,因为您不能为原始类型重载运算符,并且定义了默认运算符,因此它不接受右值。它表现出您似乎期望的行为。基本上,我们被剥夺了重新定义原始类型运算符语义的自由。
推荐阅读
- javascript - 如何使用带有登录详细信息的灯塔?
- javascript - 如何使用纯 JavaScript 更新所有子 ID
- c# - Nuget Hell:由于公钥差异,无法在 UWP 应用程序中引用 NuGet 包
- java - 使用 Keycloak 作为授权服务器,使用 Zuul 作为 API 网关
- pyspark - 在 pySpark 中定义自定义窗口函数
- ios - xcodebuild:离子电容器应用程序中的命令失败,退出代码为 65
- jquery - 将 HTML 表格数据和模型数据传递给控制器 MVC
- java - 将 SimplesamlPHP 与 Java 应用程序集成
- elasticsearch - 将 geo_shape 读取为 GeoJSON 文本
- flutter - 我怎样才能创建一个表如下