我正在阅读“Effective C ++”并尝试从规则3中编译此示例:
class TextBlock
{
public:
const char& operator[](size_t position) const
{
return text[position];
}
char& operator[](size_t position) const
{
return const_cast<char&>(
static_cast<const TextBlock&>(*this)
[position]
);
}
private:
string text;
};
这必须描述如何防止代码重复;不写相同的代码来返回非const结果。我正在使用VS2012。但是我收到了一个错误。我听说重载的函数不能有不同的返回类型,但在看到这个之后我不知道该怎么想。
答案 0 :(得分:6)
我认为这本书说的是
const char& operator[](size_t position) const
char& operator[](size_t position)
不
const char& operator[](size_t position) const
char& operator[](size_t position) const <--- extra const here
cv-qualifiers是函数签名的一部分,返回类型不是。
答案 1 :(得分:3)
正如其他人已经指出的那样,问题在于您无意中添加了const
。
然而,更重要的是,您提供的示例,来自“Effective C ++”教授Bad Things™。
它所处理的问题不是问题,而且通过演员表示用const
方法表达非const
方法的解决方案是令人厌恶的。
同时不处理真正的问题(例如易于调试,检查参数值,使用前的定义以便于阅读)。
这是更好更短的代码:
using Index = ptrdiff_t;
class TextBlock
{
private:
std::string text;
public:
auto operator[]( Index const i ) const
-> char const&
{ return text[i]; }
auto operator[]( Index const i )
-> char&
{ return text[i]; }
};
对于您没有方便的已经 - const
- 配对的底层表示的情况,您可以使用此支持机制:
template< class A, class B >
struct With_const_as_T_ { using T = typename std::remove_const<B>::type; };
template< class A, class B >
struct With_const_as_T_< A const, B > { using T = B const; };
template< class A, class B >
using With_const_as_ = typename With_const_as_T_<A, B>::T;
...用模板函数表示非const
和const
,如下所示:
class TextBlock
{
private:
std::string text;
template< class Self >
static auto at( Self& self, Index const i )
-> With_const_as_<Self, char>&
{ return self.text[i]; }
public:
auto operator[]( Index const i ) const
-> char const&
{ return at( *this, i ); }
auto operator[]( Index const i )
-> char&
{ return at( *this, i ); } // Look, no casts!
};