C++ 类模板的非类、非函数成员的显式专门化

C++ 类模板的非类、非函数成员的显式专门化,c++,C++,看看代码: template <class x> struct Foo { int getX(x *p) { return(0); } enum E12 { a }; }; template <> int Foo<int>::getX(int*) { return(-15); } template <> enum Foo<int>::E12 { a, b, c } 模板结构Foo { int get

看看代码:

template <class x> struct Foo
{
    int getX(x *p) { return(0); }
    enum E12 { a };
};

template <> int Foo<int>::getX(int*)
{
    return(-15);
}

template <> enum Foo<int>::E12
{
    a, b, c
}
模板结构Foo
{
int getX(x*p){return(0);}
枚举E12{a};
};
模板intfoo::getX(int*)
{
回报率(-15);
}
模板枚举Foo::E12
{
a、 b,c
}
正如在中所讨论的,第一个专门化是合法的,甚至可以在MSVC中工作。而
enum
的第二个专门化甚至不想编译,比如“错误C2988:无法识别的模板声明/定义”

在我看来,C++对方法来说是一种相对不合理的异常。Enum只是一个例子。同样的事情也可以应用于成员类、typedef等


我很高兴有人会对此发表评论。

这是C++11的一个非常模糊的新特性。向微软提交一份bug报告,尽管它不太可能获得优先权,因为几乎没有人知道这是允许的。正确的语法应该是

template <class x> struct Foo
{
    int getX(x *p) { return(0); }
    enum E12 { a };
};
 
template <> int Foo<int>::getX(int*)
{
    return(-15);
}
 
template <> enum Foo<int>::E12
{
    a, b, c
};
模板结构Foo
{
int getX(x*p){return(0);}
枚举E12{a};
};
模板intfoo::getX(int*)
{
回报率(-15);
}
模板枚举Foo::E12
{
a、 b,c
};
我和GCC合作过。有人能测试一下最近的叮当声吗


在C++03中,只有类和函数可以显式专用化。根据标准C++03 14.7.3/1:

以下任何一项的明确专门化:

  • 功能模板
  • 类模板
  • 类模板的成员函数
  • 类模板的静态数据成员
  • 类模板的成员类
  • 类的成员类模板或类模板
  • 类的成员函数模板或类模板
可以通过
template

成员枚举不是这种情况。(一般来说,
enum
类型总是在第一次声明时只定义一次。)

要获取模板化的
enum
typedef
,可以将其包装在类模板中。在您的情况下,它将是
Foo
的成员类模板。这样的构造称为元函数

C++11还有别名模板,类似于模板化的typedef,但它们不能显式地专门化



对于我来说,只允许类和函数被专门化,然后允许这样的模板封装其他东西,如
enum
typedef
,似乎比允许直接专门化
enum
更为一致。但是,也许该语言正朝着您喜欢的方向发展。

这是C++11的一个非常模糊的新特性。向微软提交一份bug报告,尽管它不太可能获得优先权,因为几乎没有人知道这是允许的。正确的语法应该是

template <class x> struct Foo
{
    int getX(x *p) { return(0); }
    enum E12 { a };
};
 
template <> int Foo<int>::getX(int*)
{
    return(-15);
}
 
template <> enum Foo<int>::E12
{
    a, b, c
};
模板结构Foo
{
int getX(x*p){return(0);}
枚举E12{a};
};
模板intfoo::getX(int*)
{
回报率(-15);
}
模板枚举Foo::E12
{
a、 b,c
};
我和GCC合作过。有人能测试一下最近的叮当声吗


在C++03中,只有类和函数可以显式专用化。根据标准C++03 14.7.3/1:

以下任何一项的明确专门化:

  • 功能模板
  • 类模板
  • 类模板的成员函数
  • 类模板的静态数据成员
  • 类模板的成员类
  • 类的成员类模板或类模板
  • 类的成员函数模板或类模板
可以通过
template

成员枚举不是这种情况。(一般来说,
enum
类型总是在第一次声明时只定义一次。)

要获取模板化的
enum
typedef
,可以将其包装在类模板中。在您的情况下,它将是
Foo
的成员类模板。这样的构造称为元函数

C++11还有别名模板,类似于模板化的typedef,但它们不能显式地专门化



对于我来说,只允许类和函数被专门化,然后允许这样的模板封装其他东西,如
enum
typedef
,似乎比允许直接专门化
enum
更为一致。但是,也许这种语言正朝着你喜欢的方向发展。

@MooingDuck他们悄悄地在14.7.3/1中添加了一个要点,使其合法化。我很想看看提案文件,因为从表面上看,这个特性很难被证明是正确的。问题不是C++11。在再次修复语法后,我尝试使用MSVC2008。在尝试实例化时,它现在说“错误C3113:枚举不能是模板”。@KirillKobelev抱歉,这是一个令人困惑的巧合。在仔细查看我的原始答案之前,我对C++11的这个特性一无所知。我将把它作为当前答案的补充重新发布。@potatosatter,没问题。感谢您的参与。>枚举类型总是在第一次声明时只定义一次。哈哈。枚举完全允许向前声明。@MooingDuck他们非常安静地在14.7.3/1中添加了一个要点,使其合法化。我很想看看提案文件,因为从表面上看,这个特性很难被证明是正确的。问题不是C++11。在再次修复语法后,我尝试使用MSVC2008。在尝试实例化时,它现在说“错误C3113:枚举不能是模板”。@KirillKobelev抱歉,这是一个令人困惑的巧合。在仔细查看我的原始答案之前,我对C++11的这个特性一无所知。我将把它作为当前答案的补充重新发布。@potatosatter,没问题。感谢您的参与。>枚举类型总是在第一次声明时只定义一次。哈哈。枚举完全允许向前声明。@MooingDuck,感谢您指出错误的语法。修正了,Ups,那个