首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在模板参数中定义类,为什么它无效?

在模板参数中定义类,为什么它无效?
EN

Stack Overflow用户
提问于 2016-01-09 22:16:02
回答 3查看 1.3K关注 0票数 3

假设代码:

代码语言:javascript
复制
template <class T>
class X {  };

int main(void) {
    X<class {
        int a;
    }> x;
    return 0;
}

g++ 5.1提供了以下错误消息:

代码语言:javascript
复制
prog.cpp: In function 'int main()':
prog.cpp:5:10: error: types may not be defined in template arguments
  X<class {
          ^
prog.cpp:7:2: error: expected ';' after class definition
  }> x;
  ^
prog.cpp:7:2: error: expected template-argument before ';' token
prog.cpp:7:2: error: expected '>' before ';' token
prog.cpp:7:2: error: 'main()::<anonymous class>' is/uses anonymous type
prog.cpp:7:2: error:   trying to instantiate 'template<class T> class X'
prog.cpp:7:2: error: expected '::' before ';' token
prog.cpp:7:2: error: expected identifier before ';' token
prog.cpp:7:3: error: expected primary-expression before '>' token
  }> x;
   ^
prog.cpp:7:5: error: 'x' was not declared in this scope
  }> x;
     ^

错误输出的第二行说,我们不能在模板参数中定义类型。为什么是无效的?(我的意思是,我知道这在标准上是无效的,但原因是什么呢?)

EN

回答 3

Stack Overflow用户

发布于 2016-01-09 22:19:20

第14.3.1/2号“C++ 03标准”规定:

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

这基本上意味着你不能做你想做的事情--使用一个未命名的类型作为模板参数。

我很确定C++ 11和C++ 14标准并没有修改这一段,但是可以随意验证。

更新: C++ 11确实取消了本地类型限制--现在允许模板参数,但不允许匿名类型:https://stackoverflow.com/a/4573104/634821

票数 5
EN

Stack Overflow用户

发布于 2016-01-09 23:57:39

虽然我不知道是否有很强的技术理由来限制这一限制,但没有充分理由允许这样做。在C++98中,对可以用作模板参数的类型添加了限制,这些参数可能比需要的要强,部分原因是由于对未知的恐惧(我们如何处理没有名称的类型的损坏?)

C++11在语言中添加了lambda,可以在模板中使用。Lambda是本地类型,因此取消了对本地类型的限制。但是它们不是匿名的,它们的名称是不能说出来的,是由编译器生成的。

生成这些名称并将其用于损坏的相同技术在您的特定情况下可能是可用的,尽管它们可能不能对所有未命名类型通用--编译器生成lambda名称时除其他信息外,还使用函数名,这是由于ODR保证允许使用唯一的名称。在一般情况下,可以在命名空间级别创建一个未命名的类型,在这个级别上,很难确定损坏类型的正确方式。

票数 2
EN

Stack Overflow用户

发布于 2016-01-09 22:31:16

行中有几个错误:

代码语言:javascript
复制
X<class {
    int a;
}> x;
  1. 你试图在一个不合法的地方定义一个类。
  2. 您没有提供一个类型名来实例化X
  3. 您正在尝试使用未命名的类实例化X

最简单的解决办法是使用:

代码语言:javascript
复制
struct A { int a; };
X<A> x;

如果您能够使用C++11编译器。如果您无法访问C++11编译器,则需要将struct A的定义移到main之外。

更新,回应OP的评论

允许您建议的语法需要对定义类的语法进行重大更改。目前,您需要一个语句来定义一个类,甚至一个未命名的类。

代码语言:javascript
复制
struct A { ... } ;
            //   ^^ Need this to define a class/struct

struct { ... } obj ;
               //  ^^ Need this to define an unnamed class/struct too.

用你的代码

代码语言:javascript
复制
X<class {int a} > x;
          //  ^^ There is no scope for a statement.         
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34699569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档