Can we have an anonymous struct as template argument?

我与影子孤独终老i 提交于 2020-01-21 06:29:38

问题


The title is pretty self-explanatory, but here's a simplified example:

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

}

The compiler complains when I try to use an anonymous struct as a template argument. What's the best way to achieve something like this without having to have a separate, named struct definition?


回答1:


You are not allowed to define an unnamed type as a template argument in C++03 or even in C++0x.

The best you can do it to create a named struct local to main (in C++0x1)

1 : You are not allowed to use a local type as template argument in C++03, however C++0x allows it.

Also check out the Defect Report here. The proposed solution mentions

The following types shall not be used as a template-argument for a template type-parameter:

  • a type whose name has no linkage
  • an unnamed class or enumeration type that has no name for linkage purposes (7.1.3 [dcl.typedef])
  • a cv-qualified version of one of the types in this list
  • a type created by application of declarator operators to one of the types in this list
  • a function type that uses one of the types in this list

The compiler complains when I try to use an anonymous struct as a template parameter.

Did you mean template argument? Template parameter is different from template argument.

For example

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

int main()
{
   demo <int> x; // int is template argument
}



回答2:


Your problem isn't that the struct is unnamed, it's that the struct is declared locally. Using local types as template arguments is not permitted in C++03. It will be in C++0x though, so you might try upgrading your compiler.

EDIT: Actually, your problem is that inside a template argument list isn't a legal place to put a class definition, with or without a name, according to the C++ standard.

litb points out that although it fits into the C++0x grammar, defining a type here is forbidden by [dcl.type]:

A type-specifier-seq shall not define a class or enumeration unless it appears in the type-id of an alias-declaration (7.1.3) that is not the declaration of a template-declaration.

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 }

For a while I had a question about typedef names, but litb cleared that up. They are allowed as template arguments via:

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


来源:https://stackoverflow.com/questions/4573090/can-we-have-an-anonymous-struct-as-template-argument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!