2014-05-12 77 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

@πάνταῥεῖ有时很好记住事情来自哪里;) –