2012-08-11 164 views
3

是否鑄造了C++中定義的成員函數指針的const?下面的有效代碼是?將const成員函數強制轉換爲非const

struct T { 
    void foo(int i) const { std::cout << i << std::endl;}; 
}; 

void (T::*f1)(int) const = &T::foo; 
void (T::*f2)(int)  = reinterpret_cast<void (T::*)(int)>(f1); 
T t; 
(t.*f2)(1); 

更新:

我之所以需要這個是我正在寫一個接受兩個對象和成員函數指針,它指向對象的函數。我需要一個版本的const對象(只接受const函數)和一個正常的。由於我不想重複代碼,因此我的想法是將實際代碼放在非const版本中,並從const代碼中調用它,從而丟棄任何const。

+2

即使它被定義你不應該做到這一點。 const變量是const的原因 – Gir 2012-08-11 12:56:40

+0

@Gir好吧,不是那麼容易。在一個變量上拋出const_ness基本上試圖_add writability_(即提高期望值),同時在這個方法上拋出const_ness試圖使函數免於給出「我不會改變內部狀態」的保證。較低的期望)。 – 2012-08-11 13:03:23

+2

@Gir但這些不是變量。您似乎並沒有理解'const'關鍵字在應用於函數時的含義。 – 2012-08-11 13:03:45

回答

3

編譯器吃它。 但是後面的演員陣容更有用。

再說一遍,最好不要使用它,const_cast通常只是一個快速和骯髒的解決方案,只有在沒有其他解決方案時才適用。

回答更新

如果我理解正確的話,你要使用一個對象和兩個功能。第一個函數接受const對象和const成員函數,第二個 - 非const對象和非const成員函數。

根據給定的信息,你可以改變第二個函數來接受非const對象和const成員函數。給他們一個非const對象和它的const成員函數。

+0

查看更新的問題,我添加了一個快速解釋。 – 2012-08-11 14:31:19

+0

我更新了答案。 – klm123 2012-08-11 14:45:18

+0

謝謝,我想我可以從這裏解決它。 – 2012-08-11 15:02:24

1

是的,它被定義了,但如果函數真的是const,你可能不需要它,因爲一些編譯器優化(即返回值緩存)取決於函數是const。

+0

查看更新的問題,我添加了一個快速解釋。 – 2012-08-11 14:30:54

0

我沒有看到這樣做的理由:即使可以,也會使其更具限制性。 假設你有一個類Foo:

class Foo { 
    void f() const; 
    void g(); 
} 

和一些代碼片段:

Foo a; 
const Foo b; 

然後就可以調用這兩個a.f()a.g(),但不b.g()因爲bconst。正如你所看到的,在成員函數之後放置const使它更少限制,而不是更多。

而且,通過reinterpret_cast荷蘭國際集團這個指針,你會得到具有完全相同的價值指針(由於reinterpret_cast性質),如果你嘗試調用它,你會進入相同的T :: foo的()

+0

查看更新後的問題,我添加了一個快速解釋。 – 2012-08-11 14:32:26

0

你可以做到這一點,但它沒有任何意義,無論你打電話給f2,你也可以打電話給f1。你應該以另一種方式施放。但是如果有的話,你應該投射物體,而不是功能。

void (T::*f1)(int) const = &T::foo; 
void (T::*f2)(int)  = reinterpret_cast<void (T::*)(int)>(f1); 
T t; 
(t.*f2)(1); // compiles 
(t.*f1)(1); // this compiles too!! 

但如果你有

const T t; 
(t.*f2)(1); // error t is const 
(t.*f1)(1); // still compiles 
0

的不僅是化解歧義是執行的static_cast,這基本上是一個語言功能

#include <boost/typeof/typeof.hpp> 
struct Test 
{ 
    const int& foo(); 
    const int& foo() const; 
}; 

int main() 
{ 
    typedef const int&(Test::*non_const_ptr)(); 
    typedef const int&(Test::*const_ptr)()const; 
    BOOST_TYPEOF(static_cast<non_const_ptr>(&Test::foo)) ss; 
}