何时实现非 const 强制类型转换运算符

3
我查看了StackOverflow上的问题(特别是casting operator - const vs non-const)和user-defined conversion - cppreference.com,但是我没有找到非const版本的有用示例。
在哪些情况下会使用非const转换运算符?
背景(编辑):这个问题起源于一个用于平面内存布局的“可选”模板类的简单实现。在这里,我希望将其转换为包含类型的隐式转换,我的第一种方法是这样的(没有const):
    template <typename T>
    class Optional
    {
    public:
        operator T() { return value; }
        // ...
    private:
        T value;
        // ...
    };

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

3个回答

4

一个可行的原因是当转换运算符不返回值,而是某种引用时;您不希望转换违反被转换对象的任何const属性。

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

在我的经验中,我记得有一个例子是为了帮助我们渡过难关。


什么意思?更有趣的是:它工作得好吗? - Wolf
@Wolf,基本上那个人编写了定制代码并离开了公司。几个月后必须部署该代码,但它无法正常工作,存在大量内存泄漏等问题 - 这是让它在实际上没有时间的情况下正常工作并具备所需兼容性的最短途径。它能够工作,但很丑陋。 - Niall

2
明显的答案是将其转换为左值:
class MyInt
{
  int m;

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

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


1
当调用转换运算符时,您可能需要更改对象的内部状态:
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
在大多数情况下,我会同意@Wolf的观点。这取决于你最终打算如何使用它。例如,此代码更改了对象的公共接口(CounterInt::getState()),因此它既不是逻辑上的常量也不是按位常量。但另一方面,这完全是虚构的,很可能不会出现在任何真实的代码中。 - MatthiasB
1
现在我发现你的答案比我一开始想的更接近我的问题。也许一个更有生产力的成员函数会更可接受,例如像随机数生成器这样的东西。 - Wolf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接