21

C++11中本地类的使用有什么变化吗?

在 C++03 中,本地类似乎不能用作模板参数(我记得)。

考虑这段代码,

template<typename T> void f(const T&) {}

//Note : S is a local class defined inside main()
int main() { struct S{};  f(S()); } //I want template argument to be deduced.

但它给出了编译错误(C++03模式),说(ideone):

prog.cpp:4: 错误:没有匹配函数调用 'f(main()::S)'</p>

但是,在 C++11 模式( ideone )下编译时它编译得很好,这对我来说很有意义,否则 lambda 将无法工作。所以我猜想本地类的使用至少有这种变化。我对吗?本地课程还有哪些其他变化?

请引用标准中的相关文本(C++03 和 C++11 两者),以便读者自己比较,以备将来参考。

4

3 回答 3

12

通过比较两个标准中的 §14.3.1/2 可以看出差异。

  • C++03

    本地类型、没有链接的类型、未命名类型或由这些类型中的任何一种组合而成的类型不应用作模板类型参数的模板参数。[例子:

    template <class T> class X { /* ... */ };
    void f()
    {
     struct S { /* ... */ };
     X<S> x3;        // error: local type used as template-argument
     X<S*> x4;        // error: pointer to local type used as template-argument
    }
    

    —结束示例] [注意:模板类型参数可能是不完整的类型(3.9)。]

  • C++0x (n3290)

    [ 例子:

    template <class T> class X { };
    template <class T> void f(T t) { }
    struct { } unnamed_obj;
    
    void f() {
     struct A { };
     enum { e1 };
     typedef struct { } B;
     B b;
     X<A> x1;        // OK
     X<A*> x2;       // OK
     X<B> x3;        // OK
     f(e1);          // OK
     f(unnamed_obj); // OK
     f(b);           // OK
    }
    

    —结束示例] [注意:模板类型参数可能是不完整的类型(3.9)。——尾注]

C++03 明确禁止模板类型参数中的本地类。C++11 没有,甚至包括一个有效使用此类的示例。

于 2011-11-20T19:07:30.653 回答
10

从旧标准:

(14.3) 本地类型、没有链接的类型、未命名类型或由这些类型中的任何一种复合的类型不得用作模板类型参数的模板参数。

它似乎在 C++11 标准中被删除。

更多限制:

(9.8) 局部类中的声明只能使用类型名称、静态变量、外部变量和函数以及封闭范围内的枚举数。

(9.8) 本地类不应有成员模板。

(14.5.4) 友元模板不得在本地类中声明。

(9.4.2) 本地类不应有静态数据成员。

(9.3) 本地类 (9.8) 的成员函数没有链接。

于 2011-11-20T18:59:00.410 回答
2

根据我自己的问题,限制被删除,本地类可以用作模板参数。
不过,我没有看到对新标准的提及。

于 2011-11-20T18:54:14.717 回答