标题非常明显,但这是一个简化的例子:
#include <cstdio>
template <typename T>
struct MyTemplate {
T member;
void printMemberSize() {
printf("%i\n", sizeof(T));
}
};
int main() {
MyTemplate<struct { int a; int b; }> t; // <-- compiler doesn't like this
t.printMemberSize();
return 0;
}
当我尝试使用匿名结构作为模板参数时,编译器会抱怨。在没有单独的命名结构定义的情况下,实现这样的事情的最佳方法是什么?
答案 0 :(得分:7)
不允许在C ++ 03中甚至在C ++ 0x中定义未命名类型作为模板参数。
你可以做到最好的方法来创建一个本地命名的struct(在C ++ 0x 1 中)
1:不允许在C ++ 03中使用本地类型作为模板参数,但是C ++ 0x允许它。
另请查看缺陷报告here。建议的解决方案提到
以下类型不得用作模板类型参数的模板参数:
- 名称没有链接的类型
- 一个未命名的类或枚举类型,没有用于链接目的的名称(7.1.3 [dcl.typedef])
- 此列表中某个类型的cv限定版本
- 通过将声明者运算符应用于此列表中的某个类型而创建的类型
- 使用此列表中某种类型的函数类型
当我尝试使用匿名结构作为模板参数时,编译器会抱怨。
你的意思是模板参数吗?模板参数与模板参数不同。
例如
template < typename T > // T is template parameter
class demo {};
int main()
{
demo <int> x; // int is template argument
}
答案 1 :(得分:5)
你的问题不是结构是未命名的,而是结构是在本地声明的。在C ++ 03中不允许使用本地类型作为模板参数。它将在C ++ 0x中,因此您可以尝试升级编译器。
编辑:实际上,你的问题是根据C ++标准,在模板参数列表中放置类定义(不论是否有名称)都不合法。
litb指出虽然它符合C ++ 0x语法,但[dcl.type]
禁止在此定义类型:
type-speci-seq不应该定义类或枚举,除非它出现在别名声明(7.1.3)的type-id中,而不是模板声明的声明。
simple-template-id:
template-name < template-argument-list_opt >
template-argument-list:
template-argument ..._opt
template-argument-list , template-argument ..._opt
template-argument:
constant-expression
type-id
id-expression
type-id:
type-specifier-seq abstract-declarator_opt
type-specifier-seq:
type-specifier attribute-specifier-seq_opt
type-specifier type-specifier-seq
type-specifier:
trailing-type-specifier
class-specifier
enum-specifier
class-specifier:
class-head { member-specification_opt }
有一段时间我有一个关于typedef名称的问题,但是litb清除了这个问题。它们可以通过以下方式作为模板参数:
trailing-type-specifier:
simple-type-specifier
elaborated-type-specifier
typename-specifier
cv-qualifier
simple-type-specifier:
:: opt nested-name-specifier_opt type-name
:: opt nested-name-specifier template simple-template-id
char
char16_t
char32_t
wchar_t
bool
short
int
long
signed
unsigned
float
double
void
auto
decltype-specifier
type-name:
class-name
enum-name
typedef-name
simple-template-id