2014-05-12 58 views
2

下面的代碼編譯(並運行)就好了,儘管我希望它產生編譯時錯誤:內部部分專用模板實例++忽略編譯時錯誤

#include <iostream> 

using namespace std; 

template <typename T> 
struct is_int { 
    static const bool value = false; 
}; 

template<> 
struct is_int<int> { 
    static const bool value = true; 
}; 

// General template definition with default second type parameter (void) 
template <typename A, typename B = void> 
struct Foo { 
    static const int i = 42; 
}; 

// Partially specialized template definition with possibly 
// undefined second parameter 
template<typename A> 
struct Foo<A, typename enable_if<is_int<A>::value>::type > { 
    static const int i = 56; 
}; 


int main() { 
    cout << Foo<bool>::i << endl; // Outputs '42' 
    cout << Foo<int>::i << endl; // Outputs '56' 
    return 0; 
} 

enable_if模板如果第一個參數的值是true,那麼結構Foo的部分專用化只會定義成員類型type。請參閱reference page

因此,當main函數的第一行實例化模板Foo時,編譯器究竟做了什麼?顯然,當它試圖匹配部分專業化時,它會遇到錯誤(因爲type未定義)。

它是否簡單地放棄這個選擇以避免錯誤?

+0

在C++中沒有像_partial模板特化/實例化的東西?!? –

+0

聽起來像你在談論「SFINAE」行爲,這是預期的 –

+0

@πάνταῥεῖ:糾正(希望)的標題。 – MightyNicM

回答

5

您所遇到的是模板自省的基本知識,它被稱爲SFINAE

簡而言之:當一個模板參數替換失敗時,它不會拋出,但只是「移動」並抓住下一個不會導致扣除失敗的候選人。這對做一些編譯時分析很有用。

Boost's enable_if基於SFINAE。

+0

當前標準還有['enable_if'](http://en.cppreference.com/w/cpp/types/enable_if)。我們應該放棄這種行爲來將C++ 03等同於[tag:C++]標籤_'作爲標準'! (在OP中沒有提及增強) –

+0

@πάνταῥεῖ有時很好記住事情來自哪裏;) –