2016-12-25 22 views
-1
void foo(); 
class Foomatic() { 
    void bar(); 
    void baz() 
    { 
     std::thread a(foo); // this compiles 
     std::thread b(Foomatic::bar, this); // this doesn't 
     std::thread c(&Foomatic::bar, this); // and this compiles 
     // ... 
    } 
}; 

我知道成員函數指針的正確語法是&Foomatic::bar指向成員函數的指針 - 語法

但是爲什麼Foomatic::bar不正確?那個人回來了什麼?爲什麼&Foomatic::bar是正確的?這對我來說似乎是反直覺的。

這不是重複的。您鏈接的問題會回答正確的語法,而不是解釋原因。

我在問爲什麼C++在這裏如此不一致,我已經知道語法是什麼。

+0

@Ed Heal:這不是重複的。我不問,正確的語法是什麼,因爲我知道它是什麼,但是**爲什麼**是正確的語法。答案只是說明正確的語法。 – marmistrz

+3

答案是重複的。語法不正確,因爲語言規範是這樣說的。爲什麼足球比賽長達90分鐘?因爲這就是規則所說的。 –

+3

也許真正的問題是爲什麼'a(foo)'有效,當它應該是'(&foo)'? –

回答

4

C++繼承了從C函數到函數指針的轉換,您可以將函數名稱指定給函數指針而不需要獲取地址。函數指針的這種「衰減」似乎有點不明智,並且在C中引起了一些混淆。當指向成員的指針不需要向後兼容時,C:C沒有指針給成員。因此,可以選擇不從成員名稱到成員指針的隱式轉換。由於可以在稍後添加一個設施,如果感覺有必要但很難移除,則選擇不會從成員名稱到指向成員的隱式轉換。

由於存在合理的一致接口來獲取指向函數的指針,指向成員的指針以及指向對象的指針似乎不需要從成員名稱到指向成員的隱式轉換,這是因爲存在沒有從對象名稱到指向對象的指針的隱式轉換。

從語義上來說,像T::member這樣的東西是對成員的引用,而不是指向成員的指針。但是,我不認爲有可能用當前的規範來制定這種類型。可能的是,未來的標準爲這種語法定義了一些東西。

0

如果&Foomatic::Bar是一個指針到成員函數(因爲你正在使用的地址的運營商&取函數的地址),然後Foomatic::Bar成員函數,而不是一個指針到 - 成員功能。

這與非成員函數完全相同:如果&foo是指向(非成員)函數的指針,則foo是函數。

C++和C都沒有函數作爲第一類對象,例如,你不能有一個其類型/值是一個函數的變量---只有一個指針。

至於非成員函數的語法糖特殊情況下,可以調用所述功能而不必遵從它首先明確地,例如,foo(42)是短手(*foo)(42)如果foo是指向(非成員)功能。