首页 > 后端开发 > C++ > 重载运算符是否可以消除具有用户定义类型的表达式(如'i = i”)中的未定义行为?

重载运算符是否可以消除具有用户定义类型的表达式(如'i = i”)中的未定义行为?

DDD
发布: 2024-12-22 19:27:13
原创
889 人浏览过

Does Overloading Operators Eliminate Undefined Behavior in Expressions like `i  =   i` with User-Defined Types?

重新审视未定义的行为和序列点

当 i 是内置类型时,表达式 i = i 已被标记为调用未定义的行为。但是,当 i 是用户定义类型时,它会引发有关类似表达式的行为的问题。

用户定义类型注意事项

类型 Index 定义为:

class Index {
    int state;

    public:
        Index(int s) : state(s) {}
        Index& operator++() {
            state++;
            return *this;
        }
        Index& operator+=(const Index &index) {
            state += index.state;
            return *this;
        }
        operator int() {
            return state;
        }
        Index& add(const Index &index) {
            state += index.state;
            return *this;
        }
        Index& inc() {
            state++;
            return *this;
        }
};
登录后复制

像 i.operator =(i.operator ()); 这样的表达式或 i.add(i.inc());仍然调用未定义的行为?

序列点含义

表达式 i.operator =(i.operator ());不会调用未定义的行为,因为:

  • 重载运算符是函数,它们在求值之前和之后都有序列点。
  • 运算符 () 和运算符 =() 调用因此具有良好的性能-定义的序列点。
  • 因此,表达式的行为符合预期,不会违反序列点

非表达式注意事项

原始表达式 i = i 提出了它是否是表达式的问题。如果不是,则可能不受序列点规则的约束。然而,这个论点不太可能成立,因为它被解析并作为表达式执行。

多重修改

另一个感兴趣的表达式,a[ i] = i ,由于序列点之间的潜在修改也引发了问题。然而,当 a 是重载下标运算符的用户定义类型时,它是明确定义的。

表达式复杂度

表达式 i 在 C 中是明确定义的03 因为它等价于((i.operator()).operator()).operator(),它在函数之间有明确定义的序列点

结论

涉及用户定义类型和序列点的表达式的行为取决于运算符的具体实现。重载运算符表现为函数,提供序列点。然而,一个表达式是否受序列点规则的约束可能取决于它的语法结构和作为表达式的解释。

以上是重载运算符是否可以消除具有用户定义类型的表达式(如'i = i”)中的未定义行为?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板