本地类:C++03与C++11的区别

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: error: no matching function for call to ‘f(main()::S)’

然而,当在C++11模式下编译时(ideone),它可以成功编译,这对我来说是有道理的,否则lambda将无法工作。因此,我猜至少在使用局部类方面有这种改变。我是对的吗?关于局部类还有哪些其他的变化?

请引用标准中相关的文本(C++03和C++11都要),以便读者可以自行比较并供以后参考。


至少在旧的 C++ 标准中,您不能使用局部类型实例化模板。 - Paul Manta
我清楚地记得这是从C++03到C++11的变化。局部类与模板之间的限制更多是任意的,我不确定它是否有助于编译器的编写(虽然一旦解析了局部概念,去除它们会使其更容易,但又能获得什么好处呢?)。我没有C++03标准,所以你必须相信我的话,直到有人拿到它为止。 - Matthieu M.
4
有一篇关于这个的文章 - Mankarse
@Mankarse:谢谢。看起来很有趣。我会阅读它的。 - Nawaz
3个回答

12
通过比较两个标准中的§14.3.1/2,可以看出它们之间的区别。
  • C++03

    A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter. [Example:

    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
    }
    

    —end example] [Note: a template type argument may be an incomplete type (3.9). ]

  • C++0x (n3290)

    [ Example:

    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
    }
    

    — end example ] [ Note: A template type argument may be an incomplete type (3.9). — end note ]

C++03明确禁止在模板类型参数中使用局部类。C++11不再禁止,并且甚至包括了一个有效使用这种语法的例子。


10

来自旧标准:

(14.3) 本地类型、无链接的类型、未命名的类型或由这些类型中任何一个组成的类型不得用作模板类型参数。

看起来在C++11标准中已经被删除了。

更多限制:

(9.8) 局部类中的声明仅能使用来自封闭作用域的类型名称、静态变量、外部变量和函数,以及枚举器。

(9.8) 局部类不应该有成员模板。

(14.5.4) 友元模板不应该在局部类中声明。

(9.4.2 ) 局部类不应该有静态数据成员。

(9.3) 局部类(9.8)的成员函数没有链接。


本地类的其余限制没有被解除,是否有任何原因? - the_drow
“局部类不得具有成员模板”在14.5.2中。 “局部类不得具有静态数据成员”在9.8中。只是为了澄清,所有这些限制在C++11中仍然存在。 - Potatoswatter

2
根据我的问题,现在已经取消了限制,可以将本地类用作模板参数。
但我没有看到新标准的参考文献。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接