C++中部分专用的模板实例化忽略了编译时错误

dom*_*min 2 c++ templates compile-time

下面的代码编译(并运行)就好了,即使我希望它产生编译时错误:

#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;
}
Run Code Online (Sandbox Code Playgroud)

如果第一个参数是值enable_if,则struct的部分特化中的模板Foo仅定义成员类型.请参阅参考页面.typetrue

因此,当main函数中的第一行实例化模板时Foo,编译器到底做了什么?显然,当它试图匹配部分特化时,它会遇到错误(因为type没有定义).

是否只是放弃了这个选择以避免错误?

Mar*_* A. 5

您所经历的是模板内省的基础,它被称为SFINAE.

简单地说:当模板参数替换失败时,它不会抛出而只是" 继续 "并抓住下一个不会导致扣除失败的候选者.这对于进行一些编译时分析很有用.

Boost的enable_if基于SFINAE.