2013-02-28 62 views
1

此問題已更新。請查看代碼。編譯器警告「有效C++」的方法,以避免重複const和非const成員函數

以下代碼是使用VC++ 2012年11月CTP編譯的。 Scott Meyers的書「Effective C++」建議我們應該使用避免重載const和非const成員函數的方法。但是,下面的代碼會導致警告(級別1)。由於WDK構建工具將警告視爲錯誤,因此以下代碼無法成功編譯。

還有其他更好的方法嗎?

struct A 
{ 
    int n; 

    A(int n) 
     : n(n) 
    {} 

    int Get() const 
    { 
     return n; 
    } 

    int Get() 
    { 
     return static_cast<const decltype(*this)&>(*this).Get(); 
    } 
}; 

int main() 
{ 
    const A a(8); 

    // 
    // warning C4717: 'A::Get' : recursive on all control paths, 
    // function will cause runtime stack overflow 
    // 
    a.Get(); 
} 
+0

不知道它以任何方式警告是相關的,但在概念上你的'const'版本應該是'const int的&獲取()const',即返回const的引用。 – juanchopanza 2013-02-28 09:38:36

+0

@ juanchopanza,固定。 – xmllmx 2013-02-28 09:40:45

+0

在這種特殊情況下,「重複」將是'return n;'。這是如何改進的?我們發現引入額外的代碼有時也會導致額外的錯誤... – 2013-02-28 10:00:43

回答

6

你換位兩個Get方法的機構,所以編譯器是正確的; const Get方法正在調用它自己。你現在不高興你的構建工具將警告視爲錯誤嗎? :)

交換他們圓:

int& Get() 
{ 
    return const_cast<int&>(static_cast<const A&>(*this).Get()); 
} 

const int& Get() const 
{ 
    return n; 
} 
+0

因此編譯器警告是有效的。 – 2013-02-28 09:45:34

1

回答更新問題。 (應該使這個新的問題)

static_cast<const decltype(*this)&>(*this)*thisA類型的左值,所以通過decltype(*this)表示的類型是A&(見7.1.6.2 [dcl.type.simple]/4)。

因此,您的非const Get()功能等同於:在引用類型

int Get() 
{ 
    typedef A & Aref; 
    // IMHO a const_cast would be the better choice here 
    return static_cast<const Aref&>(*this).Get(); 
} 

cv修飾符被忽略。通過參考摺疊,您的演員最終等於static_cast<A&>(*this),因此您不需要添加您需要的常量。

所以使用decl_type在這裏不起作用。如果你非常非常想使用它,你需要:

int Get() 
{ 
    // Made my suggested change of cast here 
    return const_cast<const std::remove_reference<decltype(*this)>::type&>(*this).Get(); 
} 
+0

是的。我做到了。見http://stackoverflow.com/questions/15133644/why-does-decltypethis-not-return-the-correct-type – xmllmx 2013-02-28 11:53:33