例如:
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成员函数中重复相同的逻辑。
答案 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();
}