当前位置: 首页 > 知识库问答 >
问题:

是否允许使用具有相同整数值的枚举专门化模板?

燕刚捷
2023-03-14

看看这个简单的片段:

enum class Enum1 { Value };
enum class Enum2 { Value };
template <auto> struct Foo;
template <> struct Foo<Enum1::Value> { };
template <> struct Foo<Enum2::Value> { };

clang编译了这个,但是gcc-7.2失败了:

x、 cpp:5:20:错误:重新定义“struct Foo”

此错误消息似乎无效,在第5行,写入了Enum2::Value

哪个编译器是正确的?这是符合标准的代码吗?

共有1个答案

卜方伟
2023-03-14

在[dcl.type.auto.deduct]:

包含占位符类型的类型T,以及相应的初始值设定项e,确定如下:

  • 对于使用包含占位符类型的类型声明的非类型模板参数,T是非类型模板参数的声明类型,e是相应的模板参数

这似乎表明推断的类型将是decltype(Enum1::Value),而值将是Enum1::Value

dectype(Enum1::Value)是否等于dectype(Enum2::Value)?这段代码...

static_assert(std::is_same_v<decltype(Enum1::Value), decltype(Enum2::Value)>);

...无法同时使用clang 6和g 8进行编译。

我想你可能暴露了gcc中的一个错误。正如Johannes Schaub在评论中指出的那样,还有一段支持gcc的行为。

有一个bug报告打开了:#79092。

还请注意,两个编译器都接受以下代码:

template <typename T, T> struct Foo;
template <> struct Foo<decltype(Enum1::Value), Enum1::Value> { };
template <> struct Foo<decltype(Enum2::Value), Enum2::Value> { };

模板

 类似资料:
  • 如果我有一些琐碎的东西,比如(为了澄清,我并不是说这是一个好的实现,只是一个演示成员函数部分模板专门化失败的示例): 我无法通过执行以下操作来专门化每个功能: 不幸的是,C标准不允许: 14.5.5.31、类模板局部特化成员的模板参数列表应与类模板局部特化的模板参数列表匹配类模板局部特化成员的模板参数列表应与类模板局部特化的模板参数列表匹配。 因此,唯一的解决方案(据我所知)是使用类型特征或用样板

  • 我正在尝试从整数值反序列化scala枚举。 当我尝试反序列化这个字段时,它会抛出一个错误-的值com.example.TestEnum$JsonToken.VALUE_NUMBER_INT 我看到jackson doc建议在java中使用JsonCreator,但是没有提到scala enum。 我使用默认的ScalaMapper没有任何定制在这里。

  • 我正在使用一种通信标准(我无法控制),该标准定义要在各种数据包中发送/接收的数据项。 每个项目都由自定义类型和类型相关信息定义。这些项目很少会改变。我希望能够将项目构造函数的范围限制在一个地方,并将那里的所有项目定义为(类似于枚举)。 目前,我有一个用于类型的枚举和一个用于项的类。 这已经变得难以管理,我正在寻找更好的模式/结构。 我可以有一个抽象的Item类,以及每种类型的子类。使用此设置,我不

  • 任何指导都非常感谢! 谢谢,A。

  • 在TypeScript中,我定义了一个,然后我想让一个函数接受一个参数,该参数的值是枚举的值之一。但是,TypeScript似乎不对值进行任何验证,并允许枚举之外的值。有办法做到这一点吗? 如果我使用而不是,我可以得到与我所要得到的类似的东西,但是我失去了enum的一些功能。

  • 我试图将所有映射到相同的DTO类,我希望避免为每个类型声明一个方法,或者为每个枚举字段使用。 然后在我的其他地图上 但MapStruct仍在为每种枚举类型生成一种新的映射方法,而且实现方式不符合我的需要。 有没有办法用MapStruct做到这一点?还是太神奇了D