2014-03-04 40 views
3

我讀「有效的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。但是我收到一個錯誤。我聽說重載的函數不能有不同的返回類型,但看到這個後我不知道該怎麼想。

回答

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修飾符是一個函數簽名的一部分,返回類型都沒有。

+0

是不是也不好的做法,在'string'返回一個字符的參考?似乎堆腐敗等待發生 – tenfour

+2

@tenfour不是什麼'std :: string :: operator []'做什麼? –

+0

謝謝,它的工作很好。 – Anton

3

正如其他人所指出的那樣,問題在於您無意中添加了const

但是,更重要的是你給出的例子,來自「 Effective C++ 」教壞事™。

,它與涉及的問題是沒有問題的,並將該溶液,表達在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]; } 
}; 

對於您沒有,您可以使用此機器支持方便的already- const -paired底層表示的情況下:

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; 

&hellip;發表在模板功能方面都非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! 
}; 
+0

將普通代碼合併到一個函數中並避免這種醜陋的表演是一個非常好的主意。但是,這樣做有點不同嗎?解讀發佈的例子並不那麼容易。 –

+0

非常感謝,這非常有用 – Anton

+0

還有一個問題。如果我的代碼包含比返回指針多得多的操作,那麼我的代碼是否會是一個合適的解 – Anton