enable_if
的「批評者」之一是它產生了一個完整的錯誤信息。所以例如Bjarne Stroustrup希望引入概念來解決這個問題(參見his talk (youtube)或the example (wikipedia))。`enable_if`如何讓編譯器難以生成可讀的錯誤消息?
我的問題:是什麼讓技術上對編譯器產生可讀的輸出有如此具有挑戰性,enable_if
?
enable_if
的「批評者」之一是它產生了一個完整的錯誤信息。所以例如Bjarne Stroustrup希望引入概念來解決這個問題(參見his talk (youtube)或the example (wikipedia))。`enable_if`如何讓編譯器難以生成可讀的錯誤消息?
我的問題:是什麼讓技術上對編譯器產生可讀的輸出有如此具有挑戰性,enable_if
?
std::enable_if
聽起來像一些特別的東西可以啓用/禁用函數模板並給予編譯時布爾表達式類模板 ...但事實並非如此。這裏的一個可能的實現:
template <bool TCond, typename T = void>
struct enable_if {};
template <typename T>
struct enable_if<true, T> { using type = T; };
上述手段:
如果TCond
是true
,enable_if
將定義一個內type
類型別名。
如果TCond
是false
,enable_if
將不限定內type
類型別名。
當enable_if
被用來使能/禁止的東西,我們指的是其內部::type
別名:
template <typename T,
typename = std::enable_if</* something */>::type>
void foo(T) { /* something */ }
如果::type
存在上述/* something */
條件,foo
是良好的。否則,替代失敗發生,觸發SFINAE。
編譯器不知道我們的意圖並通過跟蹤錯誤的來源來處理最終的錯誤。它並不知道我們打算在一組函數/類中啓用/禁用某個函數/類 - 因此它不會給我們提供有意義和直觀的錯誤。它能做的最好的是找出錯誤的來源並給我們一個回溯。
如果enable_if
是一個特殊的關鍵字或編譯器內在的,那麼錯誤很可能會更容易解析。
[相關](https://softwareengineering.stackexchange.com/questions/70086/why-are-c-template-error-messages-so-horrific) – CoryKramer
概念也可能產生大量錯誤消息,請參見[示例](http://honermann.net/blog/2016/07/18/refining-concepts-improving-error-messages/) – Barry