<tfoot id='qJVEc'></tfoot>

      <bdo id='qJVEc'></bdo><ul id='qJVEc'></ul>

  1. <small id='qJVEc'></small><noframes id='qJVEc'>

  2. <i id='qJVEc'><tr id='qJVEc'><dt id='qJVEc'><q id='qJVEc'><span id='qJVEc'><b id='qJVEc'><form id='qJVEc'><ins id='qJVEc'></ins><ul id='qJVEc'></ul><sub id='qJVEc'></sub></form><legend id='qJVEc'></legend><bdo id='qJVEc'><pre id='qJVEc'><center id='qJVEc'></center></pre></bdo></b><th id='qJVEc'></th></span></q></dt></tr></i><div id='qJVEc'><tfoot id='qJVEc'></tfoot><dl id='qJVEc'><fieldset id='qJVEc'></fieldset></dl></div>
    <legend id='qJVEc'><style id='qJVEc'><dir id='qJVEc'><q id='qJVEc'></q></dir></style></legend>
    1. 如果从不通过它们修改对实际 const 对象的引用,是否允许 const-casting 掉其常量性?

      Is const-casting away const-ness of references to actual const objects permitted if they are never modified through them?(如果从不通过它们修改对实际 const 对象的引用,是否允许 const-casting 掉其常量性?)
    2. <i id='DdVFd'><tr id='DdVFd'><dt id='DdVFd'><q id='DdVFd'><span id='DdVFd'><b id='DdVFd'><form id='DdVFd'><ins id='DdVFd'></ins><ul id='DdVFd'></ul><sub id='DdVFd'></sub></form><legend id='DdVFd'></legend><bdo id='DdVFd'><pre id='DdVFd'><center id='DdVFd'></center></pre></bdo></b><th id='DdVFd'></th></span></q></dt></tr></i><div id='DdVFd'><tfoot id='DdVFd'></tfoot><dl id='DdVFd'><fieldset id='DdVFd'></fieldset></dl></div>
      • <bdo id='DdVFd'></bdo><ul id='DdVFd'></ul>

        <small id='DdVFd'></small><noframes id='DdVFd'>

            <legend id='DdVFd'><style id='DdVFd'><dir id='DdVFd'><q id='DdVFd'></q></dir></style></legend>

              <tfoot id='DdVFd'></tfoot>
                <tbody id='DdVFd'></tbody>

              1. 本文介绍了如果从不通过它们修改对实际 const 对象的引用,是否允许 const-casting 掉其常量性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                我有一个抽象类,它声明了常量和非常量成员函数.为了便于讨论,我们假设它看起来像这样:

                I have an abstract class that declares const and non-const member functions. For the sake of discussion let's say it looks like this:

                class record_interface
                {
                public:
                   virtual ~record_interface() = default;
                
                   virtual void set_foo(BoundedFloat) = 0;
                   virtual BoundedFloat get_foo() const = 0;
                };
                

                这用作记录的高级表示,当保存到光盘并通过线路传输时,该记录具有不同的表示.因此,大多数实现只需要将其成员转换为所需的高级表示.

                This is used as a high-level representation of a record that has different representations when saved to disc and transferred via the wire. So most implementations just need to convert their members to the required high-level representation.

                作为有效实现的示例,让我们定义 stored_record.这用于以有损格式存储高级记录:

                As an example of a valid implementation let's define stored_record. This is used to store the high-level record in a lossy format:

                struct stored_record
                {
                    int16_t foo;
                };
                

                stored_record 可以实现 record_interface 是有道理的,但由于各种原因它不能(例如,它需要是 trivially_copyable).我们可以制作一个包装器来实现它的接口:

                It makes sense that stored_record can implement record_interface but for various reasons it can't (eg. it needs to be trivially_copyable). We can make a wrapper that implements the interface for it:

                class record_wrapper : public record_interface
                {
                public:
                  record_wrapper(stored_record & wrapped)
                    : wrapped_(wrapped) {}
                
                  void set_foo(BoundedFloat value) final { wrapped_.foo = convert_to_int16(value); }
                  BoundedFloat get_foo() const final { return convert_from_int16(wrapped_.foo); }
                
                private:
                  stored_record & wrapped_;
                };
                

                现在的问题是,当给定 const stored_record & 时,我们不能使用包装器,因为包装器存储一个可变引用.我们也不能让它存储非常量引用,因为它无法实现非常量 setter 函数.

                Now the problem is that we can't use the wrapper when given a const stored_record & since the wrapper stores a mutable reference. We also can't make it store a non-const reference as it won't be able to implement the non-const setter function.

                现在我想知道提供一个 const_cast 远离的工厂函数是否有效一个 const stored_record &const 但也返回一个 const 包装器 以便引用实际上不能被修改:

                Now I was wondering if it would be valid to provide a factory function that const_casts away a const stored_record & 's const but also returns a const wrapper so that the reference cannot actually be modified:

                record_wrapper make_wrapper(stored_record & wrapped) {return {wrapped}; }
                record_wrapper const make_wrapper(stored_record const & wrapped) { return {const_cast<stored_record &>(wrapped)}; }
                

                EDIT:返回一个 const record_wrapper 不会真正将返回值限制为 const,一个解决方案可以是返回一个 const_wrapper 或类似的东西.

                EDIT: returning a const record_wrapper will not really restrict the returned value to be const, a solution can be to return a const_wrapper<record_wrapper> or something similar.

                这是 const_cast 的有效用法还是由于 const_cast 去掉了对一个引用的 const-ness 而导致的未定义行为实际上是 const 对象 - 即使它从未被修改过.

                Is this a valid usage of const_cast or is it undefined behaviour due to const_casting away the const-ness of a reference to an actually const object - even though it is never modified through it.

                推荐答案

                Per https://en.cppreference.com/w/cpp/language/const_cast:

                const_cast 可以形成一个引用或指向实际引用 const 对象 或指向实际引用 易失性对象.通过非常量访问路径修改常量对象并通过非易失性引用易失性对象 glvalue 导致未定义的行为.

                const_cast makes it possible to form a reference or pointer to non-const type that is actually referring to a const object or a reference or pointer to non-volatile type that is actually referring to a volatile object. Modifying a const object through a non-const access path and referring to a volatile object through a non-volatile glvalue results in undefined behavior.

                因此,const_cast 本身是允许的(并且定义良好),即使通过生成的非常量引用实际修改对象是未定义的行为.

                So, the const_cast itself is allowed (and well-defined), even though it would be undefined behavior to actually modify the object via the resulting non-const reference.

                这篇关于如果从不通过它们修改对实际 const 对象的引用,是否允许 const-casting 掉其常量性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                相关文档推荐

                Constructor initialization Vs assignment(构造函数初始化 Vs 赋值)
                Is a `=default` move constructor equivalent to a member-wise move constructor?(`=default` 移动构造函数是否等同于成员移动构造函数?)
                Has the new C++11 member initialization feature at declaration made initialization lists obsolete?(声明时新的 C++11 成员初始化功能是否使初始化列表过时了?)
                Order of constructor call in virtual inheritance(虚继承中构造函数调用的顺序)
                How to use sfinae for selecting constructors?(如何使用 sfinae 选择构造函数?)
                Initializing a union with a non-trivial constructor(使用非平凡的构造函数初始化联合)
                <i id='AjMxW'><tr id='AjMxW'><dt id='AjMxW'><q id='AjMxW'><span id='AjMxW'><b id='AjMxW'><form id='AjMxW'><ins id='AjMxW'></ins><ul id='AjMxW'></ul><sub id='AjMxW'></sub></form><legend id='AjMxW'></legend><bdo id='AjMxW'><pre id='AjMxW'><center id='AjMxW'></center></pre></bdo></b><th id='AjMxW'></th></span></q></dt></tr></i><div id='AjMxW'><tfoot id='AjMxW'></tfoot><dl id='AjMxW'><fieldset id='AjMxW'></fieldset></dl></div>
              2. <small id='AjMxW'></small><noframes id='AjMxW'>

                <tfoot id='AjMxW'></tfoot><legend id='AjMxW'><style id='AjMxW'><dir id='AjMxW'><q id='AjMxW'></q></dir></style></legend>

                    <bdo id='AjMxW'></bdo><ul id='AjMxW'></ul>

                            <tbody id='AjMxW'></tbody>