【问题标题】:When to implement a non-const cast operator何时实现非常量类型转换运算符
【发布时间】:2014-08-27 12:32:59
【问题描述】:

我检查了 StackOverflow(尤其是 casting operator - const vs non-const)和 user-defined conversion - cppreference.com 上的问题,但我没有发现非常量版本的有用示例。

在哪些情况下非 const 类型转换运算符有意义?


背景(一个编辑):这个问题来自于一个简单的实现平面内存布局的可选模板类。在这里,我希望对包含的类型进行隐式强制转换,我的第一种方法是这样的(没有const):

    template <typename T>
    class Optional
    {
    public:
        operator T() { return value; }
        // ...
    private:
        T value;
        // ...
    };

在编译器提醒我之后,我很好奇这(当返回 rvalue 时)在任何情况下都是错误的。

【问题讨论】:

    标签: c++ operator-overloading constants typecast-operator


    【解决方案1】:

    一个可行的原因是强制转换操作符不返回值,而是某种类型的引用;您不希望演员表违反任何const-ness 被转换的对象。

    class Type {
      HANDLE h;
    public:
      operator HANDLE const&() const {
        return h;
      }
      operator HANDLE&() { // possibly want the non-const as well
        return h;
      }
    };
    

    根据我的经验,我想我记得一个例子,它是为了让我们摆脱困境。

    【讨论】:

    • 什么捏?更有趣的是:效果好吗?
    • @Wolf,基本上这个人编写了定制代码并离开了公司。然后代码不得不在几个月后部署,没有工作,充满了内存泄漏等等 - 这是让它工作的最短方法,并且几乎没有时间我们需要的兼容性。它有效,但很丑。
    【解决方案2】:

    显而易见的答案是转换为左值:

    class MyInt
    {
      int m;
    
    public:
      operator int& () { return m; }
      operator int () const { return m; }
    };
    

    除此之外,我想不出任何具体的例子。我想这在某些特定领域的语言中可能是有意义的,其中整个 C++ 类型系统只是提供一些语法的工具。

    【讨论】:

      【解决方案3】:

      当调用转换运算符时,您可能需要更改对象的内部状态:

      class CounterInt {
      private:
        int m_value;
        int m_state;
      public:
        CounterInt(int val) : m_value(val), m_state(0) {}
        operator int() {
          ++m_state;
          return m_value;
        }
        int getState() {return m_state;}
      };
      

      如果你的转换操作符是 const,这是不可能的。这是否是一个好主意(或者您是否应该使状态可变)是另一个问题。

      【讨论】:

      • 好的,我可能会通过使m_state 可变来解决这个问题;我认为这是可变的目的。
      • @Wolf 在大多数情况下我会同意。这取决于您最终打算如何使用它。例如,此代码更改了对象的公共接口 (CounterInt::getState()),因此它既不是逻辑也不是按位 const。但另一方面,这完全是虚构的,很可能不会出现在任何真实代码中。
      • 现在我发现你的答案比我最初想象的更接近我的问题。也许更高效的成员函数会更容易接受,例如随机数生成器。
      猜你喜欢
      • 1970-01-01
      • 2018-06-23
      • 2014-03-27
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 2014-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多