从枚举器获取枚举类型

Get enumeration type from enumerator

本文关键字:枚举 类型 获取      更新时间:2023-10-16

假设我有这样的代码:

#include <cstdio>
enum Foo { Foo_A, Foo_B };
enum Bar { Bar_A, Bar_B };
template<typename enumeration, int enumerator>
struct tpl;
template<int enumerator>
struct tpl<Foo, enumerator>
{
    tpl() { printf("Foo: %dn", enumerator); }
};
template<int enumerator>
struct tpl<Bar, enumerator>
{
    tpl() { printf("Bar: %dn", enumerator); }
};
int main()
{
    tpl<Foo, Foo_A> foo_a;
    tpl<Foo, Foo_B> foo_b;
    tpl<Bar, Bar_A> bar_a;
    tpl<Bar, Bar_B> bar_b;
    return 0;
};

有没有办法减少使用站点的"重复"?也就是说,我不能从枚举器"Foo_A"等中推导出枚举类型"Foo",并以某种方式在上面的模板代码中使用它吗?枚举类在这里有帮助吗?

您的问题的答案是,没有目前没有办法做到这一点。你所面对的是众所周知的template <typename T, T t>习语。事实上,如果你用谷歌搜索,你会发现有近75000次点击,而且没有解决办法。你必须尽你所能做到专业化。


但好消息就在眼前。在过去的十年里,这已经多次向标准委员会提出:

  • N3405提出了template <typename T t>的容差。其中T是类型,t是值,只有一个值作为模板参数传递
  • N3601提出template <typename T, T t>是一种特殊情况,编译器只接受单个值作为模板参数,并由此推断出Tt
  • N4469建议允许关键字auto指定一个元参数:template <auto t>,以便将一个值作为模板参数t传递,并推导出其类型

2015年5月4日,在Lenexa举行的会议上,N4469终于获得了支持,并在标准委员会会议上提出了修订要求:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4539.html#9

第一次修订P0127R0于2015年9月25日提交。

2016年3月4日提交了后续修订:P0127R1,建议对概念工作草案部分进行编辑。

P0127R2专注于充分说明工作草案中非概念部分的习语变化,因为尚不清楚概念是否会包含在C++17中。该修订于2016年6月23日被接受为C++17标准:http://developerblog.redhat.com/2016/07/13/red-hat-iso-c-standards-meeting-june-2016-core-language/

因此,随着C++17的到来,您将能够处理template <typename T, T t>习惯用法并使用:

template <auto t>
struct tpl{
    tpl(){ cout << typeid(decltype(t)).name() << ": " << t << endl; }
};