Const函数调用非const,反之亦然(以避免重复)?

Sil*_*ane 12 c++ const function

使用一个优于另一个是否有任何优势:

class Foo
{
public:
    const int& get() const
    {
        // stuff here
        return myInt;
    }

    int& get()
    {
        return const_cast<int&>(static_cast<const Foo*>(this)->get());
    }
};
Run Code Online (Sandbox Code Playgroud)

要么

class Foo
{
public:
    int& get()
    {
        // stuff here
        return myInt;
    }

    const int& get() const
    {
        return const_cast<Foo*>(this)->get();
    }
};
Run Code Online (Sandbox Code Playgroud)

我只使用了第一个,但我刚看到第二个用在某个地方,所以我很想知道.

注释// stuff here可能是一个非平凡的检查,如检索表的索引,以便返回表的成员的引用(例如:),myInt = myTable[myComputedIndex];所以我不能只是公开它.因此,表和任何成员都不是const.

Cur*_*ous 20

如果你必须创建一个不可知的函数,并避免重复,一个巧妙的方法就是将实现委托给模板,例如

class Foo {
private: 

    int my_int;
    template <typename ThisPtr>
    static auto& get(ThisPtr this_ptr) { 
        return this_ptr->my_int;
    }

public:
    int& get() {
        return get(this);
    }

    const int& get() const {
        return get(this);
    }
};
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以避免与使用相关的恐惧const_cast,mutable以及在此类情况下尝试减少代码重复的其他内容.如果您遇到问题,编译器会通知您.

  • 非常巧妙地使用模板参数推导.我仍然希望C++能够避免代码重复这些重载. (5认同)
  • 我会用那个.如果只有委员会可以动摇接受它.. (3认同)
  • "*通过const_cast将const对象转换为非const版本是未定义的行为.*"这不是真的.试图修改这个非const-but-actual-const对象的是UB. (2认同)
  • 是的,修改后的版本更好了谢谢.羞耻你删除它;) (2认同)

dav*_*mac 9

忽略你是否真的需要一个getter的问题,在a const和non const方法中复制功能时的最佳解决方案是让non const方法调用const方法并抛弃const结果的性质(即两个中的第一个)你在问题中提出的替代方案).

原因很简单:如果你反过来这样做(使用非const方法中的逻辑),你可能会意外地最终修改一个const对象,并且编译器在编译时不会捕获它(因为该方法不是声明const) - 这将有未定义的行为.

当然,如果"getter"实际上不是一个getter(例如,如果它正在做的事情比仅返回对私有字段的引用更复杂的话),那么这只是一个问题.

此外,如果您不受C++ 11约束,Curious在其答案中提供的基于模板的解决方案是另一种避免此问题的方法.