6

例如:

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 成员函数中重复相同的逻辑。

4

2 回答 2

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;
};

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

于 2012-12-06T19:26:12.400 回答
1

我认为,在这里使用 cast 是可以的,但如果你绝对想避免它,你可以使用一些模板魔法:

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();
}
于 2012-12-06T19:52:53.080 回答