当调用来自同一个非const版本的重载成员函数时,是否可以删除const限定符?

时间:2012-12-06 19:19:50

标签: c++ user-interface const

例如:

struct B{};

struct A {

 const B& findB() const { /* some non trivial code */ }

 // B& findB() { /* the same non trivial code */ }

 B& findB() { 
       const A& a = *this;
       const B& b = a.findB();
       return const_cast<B&>(b);
  }
};

我想避免在常量findB和非常量findB成员函数中重复相同的逻辑。

2 个答案:

答案 0 :(得分:7)

是的,您可以将对象转换为const,调用const版本,然后将结果转换为非const

return const_cast<B&>(static_cast<const A*>(this)->findB());

仅当相关对象最初未声明为const时,才能安全地删除const。由于您处于非const成员函数中,因此您可以知道这种情况,但这取决于实现。考虑:

class A {
public:

    A(int value) : value(value) {}

    // Safe: const int -> const int&
    const int& get() const {
        return value;
    }

    // Clearly unsafe: const int -> int&
    int& get() {
        return const_cast<int&>(static_cast<const A*>(this)->get());
    }

private:
    const int value;
};

一般来说,我的会员职能很短,所以重复是可以容忍的。您有时可以将实现分解为私有模板成员函数,并从两个版本中调用它。

答案 1 :(得分:1)

我认为,在这里使用强制转换是可以的,但是如果你肯定想要避免它,你可以使用一些模板魔术:

struct B
{
    B(const B&)
    {
        std::cout << "oops I copied";
    }
    B(){}
};

struct A {
public:
    A(){}
    A(const A&){ std::cout << "a is copied:(\n";}
    const B& findB() const { return getter(*this); }    
    B& findB() { return getter(*this); }

private:
    template <typename T, typename V>
    struct same_const
    {
        typedef V& type;
    };

    template <typename T, typename V>
    struct same_const<const T, V>
    {
        typedef const V& type;
    };

    template <typename T>
    static typename same_const<T,B>::type getter(T& t) { return t.b;}

    B b;

};

int main()
{
    A a;
    const A a_const;
    const B& b1 = a.findB();
    B& b2 = a.findB();

    const B& b3 = a_const.findB();
    //B& b4 = a_const.findB();
}