C++11 模板实参

C++11 模板实参,在C++98中,标准对模板实参的类型还有一些限制。具体地讲,局部的类型和匿名的类型在C++98中都不能做模板类的实参。比如,如代码清单2-30所示的代码在C++98中很多都无法编译通过。
代码清单2-30

template <typename T> class X {};
template <typename T> void TempFun(T t){};
struct A{} a;
struct {int i;}b;             // b是匿名类型变量
typedef struct {int i;}B;    // B是匿名类型
void Fun()
{
    struct C {} c;            // C是局部类型
    X<A> x1;     // C++98通过,C++11通过
    X<B> x2;     // C++98错误,C++11通过
    X<C> x3;     // C++98错误,C++11通过
    TempFun(a); // C++98通过,C++11通过
    TempFun(b); // C++98错误,C++11通过
    TempFun(c); // C++98错误,C++11通过
}

我们定义了一个模板类X和一个模板函数TempFun,然后分别用普通的全局结构体、匿名的全局结构体,以及局部的结构体作为参数传给模板。可以看到,使用了局部的结构体C及变量c,以及匿名的结构体B及变量b的模板类和模板函数,在C++98标准下都无法通过编译。而除了匿名的结构体之外,匿名的联合体以及枚举类型,在C++98标准下也都是无法做模板的实参的。如今看来这都是不必要的限制。所以在C++11中标准允许了以上类型做模板参数的做法,故而用支持C++11标准的编译器编译以上代码,代码清单2-30所示代码可以通过编译。

不过值得指出的是,虽然匿名类型可以被模板参数所接受了,但并不意味着以下写法可以被接受,如代码清单2-31所示。
代码清单2-31

template <typename T> struct MyTemplate { };
int main() {
    MyTemplate<struct { int a; }> t; // 无法编译通过, 匿名类型的声明不能在模板实参位置
    return 0;
}

在代码清单2-31中,我们把匿名的结构体直接声明在了模板实参的位置。这种做法非常直观,但却不符合C/C++的语法。在C/C++中,即使是匿名类型的声明,也需要独立的表达式语句。要使用匿名结构体作为模板参数,则可如同代码清单2-30一样对匿名结构体作别名。

酷客教程相关文章:

赞(0)

评论 抢沙发

评论前必须登录!