【问题标题】:Dynamically iterate over static information动态迭代静态信息
【发布时间】:2019-09-04 02:25:00
【问题描述】:

假设我有一些专门针对每种枚举类型的类:

enum MyEnum {
  EnumA = 0, EnumB, EnumSize
};

template <enum MyEnum> 
class StaticEnumInfo {

};

template <> 
class StaticEnumInfo<EnumA>{
  typedef bool type;
  const std::string name = "EnumA";
};

template <> 
class StaticEnumInfo<EnumB>{
  typedef int type;
  const std::string name = "EnumB";
};

是否可以遍历所有名称并打印它们? 我想写这样的东西:

for(MyEnum i = EnumA; i < EnumSize; ++i){
    // Doesn't make sense, I know.
    std::cout << StaticEnumInfo<i>::name << std::endl;
}

我知道我可以在其他地方创建一个映射来解决这种映射(对于字符串,而不是类型......)

我无权使用 boost

【问题讨论】:

  • C++ 还没有反射。如果您搜索如何迭代枚举,您将获得许多解决该问题的方法示例。
  • 否 您不能将运行时数据更改为编译时常量。需要一个映射“函数”,所以不妨映射到名称。

标签: c++ templates specialization


【解决方案1】:

在正确的expansion statements 可用之前,您始终可以这样做:

template <typename T, T... S, typename F>
constexpr void for_sequence(std::integer_sequence<T, S...>, F&& f) {
    (static_cast<void>(f(std::integral_constant<T, S>{})), ...);
}

并像这样使用它:

for_sequence(
    std::make_integer_sequence<int, EnumSize>{},
    [&](auto i) {
        constexpr auto index = static_cast<MyEnum>(int{i});
        std::cout << StaticEnumInfo<index>::name << std::endl;
    }
);

但是要小心,因为它只有在所有枚举成员都是顺序的情况下才有效。

Live example

【讨论】:

  • 您确定模板 for 将允许 constexpr 循环迭代器,而不仅仅是 template for (auto i : std::make_index_sequence&lt;EnumSize&gt;{}) 吗?
  • 需要为 index_sequence 提供get&lt;I&gt;,这就是为什么我询问您提供的模板
  • @MasterID 我添加了扩展声明提案的链接
猜你喜欢
  • 2010-10-28
  • 1970-01-01
  • 2016-06-18
  • 2022-06-22
  • 1970-01-01
  • 2021-12-02
  • 1970-01-01
  • 2017-04-04
  • 2017-01-13
相关资源
最近更新 更多