【问题标题】:const_cast: modifying a formerly const value is only undefined if the original variable is constconst_cast:仅当原始变量为 const 时,修改以前的 const 值才是未定义的
【发布时间】:2020-08-28 08:21:36
【问题描述】:

https://stackoverflow.com/a/332086/462608

仅当原始变量为 const 时,修改以前的 const 值才是未定义的

...

如果你用它来去掉对没有用 const 声明的东西的引用的 const,它是安全的。

...

这在重载基于 const 的成员函数时很有用,例如。也可以用来给对象添加const,比如调用成员函数重载。

我无法理解上述引文的含义。我请求你给我一些例子来说明这些引用的意思。

【问题讨论】:

  • The example code on cppreference.com 提供了一些有用的说明。
  • 关于第一点,重要的是要理解为什么 const_casting 一个 const 变量是未定义的。 This answer很好解释
  • “以前”是一个错字,它可能意味着“正式”

标签: c++ c++11


【解决方案1】:

关于你的前两个引号:

void do_not_do_this(const int& cref) {
    const_cast<int&>(cref) = 42;
}

int main() {
    int a = 0;
    // "if you use it to take the const off a reference 
    // to something that wasn't declared with const, it is safe."
    do_not_do_this(a);  // well-defined
        // a is now 42.
    
    // "modifying a formerly const value is only 
    //  undefined if the original variable is const"
    const int b = 0;
    do_not_do_this(a);  // undefined behavoiur
}

关于您的最终报价:

// "This can be useful when overloading member functions based
//  on const, for instance. It can also be used to add const
//  to an object, such as to call a member function overload."
class A {
    const int& get() const
    {
        // ... some common logic for const and
        // non-const overloads.
        return a_;
    }

    int& get() {
        // Since this get() overload is non-const, the object itself
        // is non-const in this scope. Moreover, the a_ member
        // is non-const, and thus casting away the const of the return
        // from the const get() (after 'this' has been casted to
        // const) is safe.
        A const * const c_this = this;
        return const_cast<int&>(c_this->get());
    }
    
private:
    int a_{0}; 
}

【讨论】:

    【解决方案2】:

    这个怎么样:

    #include <iostream>
    void foo(const int& ub, const int& ok)
    {
        const_cast<int&>(ub) = 0.0; // undefined behaviour - the original object is const
        const_cast<int&>(ok) = 1.0; // this is fine - the original object is not const
    }
    
    int main()
    {
        const int ub = 1.0;
        int ok = 0.0;
        foo(ub, ok);
        std::cout << ub << " " << ok << std::ends;
    }
    

    注意普通编译器的输出是1 1:基本原理是编译器知道ub 不能在main 中改变,所以它在std::cout 调用中用1 代替ub

    您的第三段暗示非const 成员函数的函数体调用const 版本作为避免代码重复的手段。

    【讨论】:

      猜你喜欢
      • 2015-02-02
      • 2012-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      相关资源
      最近更新 更多