0

考虑以下模板递归函数。其目的是创建一个向量,该向量包含枚举类 EnumClassName 中的所有值,其关联的谓词函数为其bool xxx<N>()返回true

template <EnumClassName N = EnumClassName::LAST_ENUM_VALUE> 
std::vector<EnumClassName> xxx_stuff()
{
    std::vector<EnumClassName> v = xxx_stuff<EnumClassName(static_cast<int>(N) - 1)>();

    if (xxx<N>()) {
        v.emplace_back(N);
    }
    return v;
}

使用递归基本情况:

template <> std::vector<EnumClassName> xxx_stuff<EnumClassName::FIRST_ENUM_VALUE>()
{
    return {};
}

现在假设有 10 个这样的函数,唯一不同的是xxx名称。即我们有alpha_stuff带有相应谓词函数的函数alpha<N>beta_stuff带有相应谓词函数beta<N>等的函数。

有没有办法不将上述函数重复 10 次,唯一的区别是在每个重复项中替换xxxwithalpha等?beta

我不能只遍历枚举值,因为这些xxx<N>函数又会调用另一个函数yyy<N>,该函数不会接受运行时生成的模板参数<N>(请原谅我的行话,我实际上不知道我在说什么或者这个有效,我只知道当我以这种方式尝试时它给了我编译错误)。

4

1 回答 1

0

您不能将函数模板作为参数或重载函数传递,但可以将调用包装在一个类型中,然后

template <typename EnumClassName,
          EnumClassName N = EnumClassName::LAST_ENUM_VALUE,
          typename F> 
std::vector<EnumClassName> xxx_stuff(F&& f)
{
    std::vector<EnumClassName> v =
        xxx_stuff<EnumClassName, EnumClassName(static_cast<int>(N) - 1)>(f);

    if (f(std::integral_constant<EnumClassName, N>{})) {
        v.emplace_back(N);
    }
    return v;

}

有用法

auto v = xxx_stuff<E>([](auto n) { return xxx<n()>(); });

演示

注意:可以使用std::integer_sequence.

于 2022-02-14T10:38:39.390 回答