不能仅通过返回类型来区分过载功能

时间:2014-03-04 11:24:44

标签: c++ overloading

我正在阅读“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。但是我收到了一个错误。我听说重载的函数不能有不同的返回类型,但在看到这个之后我不知道该怎么想。

2 个答案:

答案 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;

...用模板函数表示非constconst,如下所示:

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