我们可以将匿名结构作为模板参数吗?

时间:2011-01-01 03:28:03

标签: c++ templates parameters struct anonymous-types

标题非常明显,但这是一个简化的例子:

#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;

}

当我尝试使用匿名结构作为模板参数时,编译器会抱怨。在没有单独的命名结构定义的情况下,实现这样的事情的最佳方法是什么?

2 个答案:

答案 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