假设代码:
template <class T>
class X { };
int main(void) {
X<class {
int a;
}> x;
return 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;
^错误输出的第二行说,我们不能在模板参数中定义类型。为什么是无效的?(我的意思是,我知道这在标准上是无效的,但原因是什么呢?)
发布于 2016-01-09 22:19:20
第14.3.1/2号“C++ 03标准”规定:
本地类型、没有链接的类型、未命名类型或由这些类型中的任何类型组合而成的类型不应用作模板类型参数的模板参数。
这基本上意味着你不能做你想做的事情--使用一个未命名的类型作为模板参数。
我很确定C++ 11和C++ 14标准并没有修改这一段,但是可以随意验证。
更新: C++ 11确实取消了本地类型限制--现在允许模板参数,但不允许匿名类型:https://stackoverflow.com/a/4573104/634821
发布于 2016-01-09 23:57:39
虽然我不知道是否有很强的技术理由来限制这一限制,但没有充分理由允许这样做。在C++98中,对可以用作模板参数的类型添加了限制,这些参数可能比需要的要强,部分原因是由于对未知的恐惧(我们如何处理没有名称的类型的损坏?)
C++11在语言中添加了lambda,可以在模板中使用。Lambda是本地类型,因此取消了对本地类型的限制。但是它们不是匿名的,它们的名称是不能说出来的,是由编译器生成的。
生成这些名称并将其用于损坏的相同技术在您的特定情况下可能是可用的,尽管它们可能不能对所有未命名类型通用--编译器生成lambda名称时除其他信息外,还使用函数名,这是由于ODR保证允许使用唯一的名称。在一般情况下,可以在命名空间级别创建一个未命名的类型,在这个级别上,很难确定损坏类型的正确方式。
发布于 2016-01-09 22:31:16
行中有几个错误:
X<class {
int a;
}> x;X。X。最简单的解决办法是使用:
struct A { int a; };
X<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. https://stackoverflow.com/questions/34699569
复制相似问题