2013-07-12 62 views
17

如果函數模板返回decltype(auto)(或使用auto的另一個類型說明符),但返回語句不合格,那麼SFINAE的結果是什麼? return聲明是否被認爲是函數簽名的直接上下文?SFINAE和decltype(自動)

N3690草案中沒有任何內容似乎需要這樣做。默認情況下,我猜SFINAE不適用。

這似乎是不幸的,因爲你可以寫一個函數來轉發到另一個函數,但是你不能在寫代碼的時候使它的存在有條件的在委託上。此外,由於this不能在函數簽名中使用,因此檢查是否存在同位體非靜態成員函數是不可能的,因爲沒有decltype(auto)。然而,這表明一個根本性問題,因爲decltype(auto)提供了一種路徑來將類類型視爲在成員簽名中是完整的,如果不是。

是否有提案被寫入,或者有問題在任何地方進行過正式分析?

在會員簽名中將類類型視爲完整的能力可能會產生其他影響......但這只是另一個問題的佐證。

+0

我一直在想這個。可悲的是,我也一直懶得遵循1y的建議...... – sehe

+0

@MarkGarcia是的,這是一個給定的。我只是在問題的末尾添加了一個註釋;非模板成員可能仍然可能向暮光區打開一個蟲洞。 – Potatoswatter

+0

如果在這個問題中有一些例子,那麼對於像我這樣的愚蠢來說就會更容易理解。 :) – iammilind

回答

15

但是return語句不合格,SFINAE的結果是什麼?

proposal-n3638說,

SFINAE

由於返回類型被實例化模板,如果形成不良的實例推斷,這將導致一個錯誤,而不是一個替代失敗。這允許自動函數返回一個lambda,這是使用decltype(返回的表達式)模式不可能的。

希望這就是你要找的。

+1

賓果!正是我在找的東西。我需要現在去,但稍後我會閱讀它來弄清楚它們如何協調成員實例化與不完整類型。 – Potatoswatter

3

上納瓦茲的鏈接跟進,其餘問題由N3690回答§7.1.6.4/ 11:

如果一個實體與undeduced佔位符類型的類型需要確定一個表達式的類型,該計劃是不合格的。

這意味着即使SFINAE使用了返回類型推導,它也不能用於查詢另一個函數聲明。在處理return語句之前,並且在處理了之前成員的定義之後,該簽名基本上無效,該語句發生在class {}定義的大括號處。

在某種意義上說,所有構件decltype(auto)功能不全相對於在同一類前述功能:

struct s { 
    void f() { a(); } // error: use of ‘auto s::a()’ before deduction of ‘auto’ 
    auto a() { return 3; } 
}; 

這是GCC的投訴;如果成員聲明被撤銷,它就會消失。這是因爲在達到類定義的}時,函數定義按聲明的順序處理。如果在return 3;之前處理語句a();,則該程序不合格。