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

non*_*all 11 c++ parameters templates 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;

}
Run Code Online (Sandbox Code Playgroud)

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

Pra*_*rav 7

您不能在C++ 03中甚至在C++ 0x中将未命名的类型定义为模板参数.

最好的做法是创建一个本地命名的struct(在C++ 0x 1中)

1:您不允许在C++ 03中使用本地类型作为模板参数,但C++ 0x允许它.

另请参阅此处的缺陷报告.建议的解决方案提到

以下类型不能用作模板类型参数的模板参数:

  • 名称没有链接的类型
  • 一个未命名的类或枚举类型,没有用于链接目的的名称(7.1.3 [dcl.typedef])
  • 此列表中某个类型的cv限定版本
  • 通过将声明符运算符应用于此列表中的某个类型而创建的类型
  • 使用此列表中某种类型的函数类型

当我尝试使用匿名结构作为模板参数时,编译器会抱怨.

你的意思是模板参数吗?模板参数与模板参数不同.

例如

template < typename T > // T is template parameter
class demo {};

int main()
{
   demo <int> x; // int is template argument
}
Run Code Online (Sandbox Code Playgroud)

  • @Prasoon:谢谢.看起来这个限制肯定会在C++ 0x中删除.仍然无法在模板参数列表中定义类型,这是代码实际提出的问题(与标题相对). (2认同)

Ben*_*igt 6

您的问题不是结构未命名,而是结构在本地声明。在C ++ 03中,不允许将本地类型用作模板参数。不过它将是C ++ 0x,因此您可以尝试升级编译器。

编辑:实际上,您的问题是,根据C ++标准,在模板参数列表内放置类定义(带有或不带有名称)不是合法的地方。

litb指出,尽管它适合C ++ 0x语法,但禁止在此处定义类型[dcl.type]

除非它出现在不是模板声明的声明的别名声明(7.1.3)的type-id中,否则类型规范的seq不应定义类或枚举。

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-speci?er-seq abstract-declarator_opt

type-speci?er-seq:
    type-speci?er attribute-speci?er-seq_opt
    type-speci?er type-speci?er-seq

type-speci?er:
    trailing-type-speci?er
    class-speci?er
    enum-speci?er

class-speci?er:
    class-head { member-speci?cation_opt }
Run Code Online (Sandbox Code Playgroud)

有一阵子我有一个关于typedef名称的问题,但是litb清除了这个问题。可通过以下方式将它们用作模板参数:

trailing-type-speci?er:
    simple-type-speci?er
    elaborated-type-speci?er
    typename-speci?er
    cv-quali?er

simple-type-speci?er:
    :: opt nested-name-speci?er_opt type-name
    :: opt nested-name-speci?er template simple-template-id
    char
    char16_t
    char32_t
    wchar_t
    bool
    short
    int
    long
    signed
    unsigned
    float
    double
    void
    auto
    decltype-speci?er

type-name:
    class-name
    enum-name
    typedef-name
    simple-template-id
Run Code Online (Sandbox Code Playgroud)