为什么C++标准库运算符接受右值
Why do the C++ standard library operators accept rvalues?
当我运行以下代码时:
std::string myString = "I'm a string.";
const std::string::iterator &myIterator = ++myString.begin();
char c = *myIterator;
std::cout << c << std::endl;
我得到一个分段错误(使用 O3 优化编译)。我认为这是因为 ++
运算符返回的是 std::string::iterator &
而不是 std::string::iterator
,因此我们得到了对临时的引用。是否有原因不实现这会导致编译错误?即,为什么签名不是以下内容?
std::string::iterator &std::string::iterator::operator++() &;
或者更好的是,为什么规范不需要以下签名,以便我们可以毫无问题地处理右值?
std::string::iterator &std::string::iterator::operator++() &;
std::string::iterator std::string::iterator::operator++() &&;
您发布的代码对我来说似乎是合法的:std::string::iterator myIterator = ++myString.begin();
将迭代器引用复制到myIterator
中,因此没有对临时的悬而未决的引用。
我的心理调试能力告诉我,你的实际代码有两个问题之一:
- 您的字符串实际上是空的,即使您认为它包含文本。在这种情况下,
++begin()
无效。
获取迭代器 - 副本后,以使迭代器无效的方式更改字符串。
@M.M的评论很有见地。特别是,我的第二个建议将限制库在实现迭代器中的选项,因为迭代器不需要作为右值递增(参考:http://en.cppreference.com/w/cpp/iterator/next),事实上,std::string::iterator 可以实现为 char *,它不能作为右值递增。
选择是否遵循我的第一个建议似乎是一个库实现决策,因为标准规定了迭代器可以做什么,而不是它们不能做什么,以免不必要地限制哪些类型可以充当迭代器。当然,此时,更改实现可能会导致用户代码的重大更改。
相关文章:
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 重载运算符new[]的行为取决于析构函数
- 如何防止clang格式在流运算符调用之间添加换行符<<