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

C++ 在模板参数中定义类,为什么它无效?,c++,C++,假设代码: template <class T> class X { }; int main(void) { X<class { int a; }> x; return 0; } 模板 类X{}; 内部主(空){ X; 返回0; } g++5.1给出以下错误消息: prog.cpp: In function 'int main()': prog.cpp:5:10: error: types may not be define

假设代码:

template <class T>
class X {  };

int main(void) {
    X<class {
        int a;
    }> x;
    return 0;
}
模板
类X{};
内部主(空){
X;
返回0;
}
g++5.1给出以下错误消息:

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;
     ^
prog.cpp:在函数“int main()”中:
prog.cpp:5:10:错误:模板参数中可能未定义类型
X;
^
prog.cpp:7:2:错误:在“;”之前应该有模板参数代币
程序cpp:7:2:错误:在“;”之前应为“>”代币
prog.cpp:7:2:错误:“main()::”是/使用匿名类型
prog.cpp:7:2:错误:尝试实例化“模板类X”
程序cpp:7:2:错误:应为“:”之前“;”代币
prog.cpp:7:2:错误:在“;”之前应该有标识符代币
prog.cpp:7:3:错误:在“>”标记之前应该有主表达式
}>x;
^
prog.cpp:7:5:错误:未在此作用域中声明“x”
}>x;
^

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

<P>03。 本地类型、无链接的类型、未命名类型或 由这些类型中的任何一种混合而成的混合物不得用作混合物 模板类型参数的模板参数

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

我非常肯定C++ 11和C++ 14标准没有修改这段,但是可以自由地验证。
< P>更新:C++ 11确实提升了局部类型限制,这是目前模板参数所允许的,但不是匿名类型:

行中有几个错误:

X<class {
    int a;
}> x;
如果您能够使用C++11编译器。如果您没有访问C++11编译器的权限,则需要将
struct a
的定义移到
main
之外

更新,回应OP的评论

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

struct A { ... } ;
            //   ^^ Need this to define a class/struct

struct { ... } obj ;
               //  ^^ Need this to define an unnamed class/struct too.
用你的代码

X<class {int a} > x;
          //  ^^ There is no scope for a statement.         
X;
//^^语句没有作用域。

没有充分的理由允许它,尽管我不确定是否有强有力的技术原因来限制它。在C++98中,对可用作模板参数的类型添加了限制,这些类型可能比需要的更强大,部分原因是担心未知(我们如何处理没有名称的类型的混乱?)

C++11在语言中添加了lambdas,可以在模板中使用。lambda是本地类型,因此取消了对本地类型的限制。但是它们不是匿名的,它们的名字只是无法用语言表达,并且是由编译器生成的


生成这些名称并使用它们进行破坏的相同技术可能在您的特定情况下可用,尽管它们可能不适用于所有未命名的类型——编译器生成lambda名称时使用函数名等信息,由于ODR,函数名保证允许唯一的名称。在一般情况下,一个未命名的类型可以在命名空间级别创建,在那里难以确定正确的类型。

我不认为C++标准允许简单明了。这有什么用?在决定语言是否支持某个功能时,需要在已知的好处、未来可能的用法、语言增加的复杂性和实现难度之间取得平衡。如果左边什么都没有。。。你不仅仅是为了添加功能而添加功能。与其问为什么这是不允许的,不如试着阐明允许你的示例会有什么好处,从而证明接受语言的额外复杂性(解析这样的结构)并在编译器中实现它们是合理的。这种功能可能在代码混淆竞赛中被利用,但这更多的是一个反对而非支持它的论点。@jnbrq CanberkSönmez:这是一个更难的问题,我没有答案。@jnbrq CanberkSönmez,阅读书籍/文章,与同龄人交谈,编程,然后重复。当然,错误是显而易见的。我正在努力理解为什么这是非法的。标准中禁止的事情背后的逻辑是什么?@jnbrq CanberkSönmez,你是在试图找到标准中使代码非法的相关部分,还是在试图理解为什么语言是这样定义的?我试图理解为什么语言是这样定义的。
X<class {int a} > x;
          //  ^^ There is no scope for a statement.