如何将矢量元素馈送到模板

How to feed vector elements to a template

本文关键字:元素      更新时间:2023-10-16

我需要使用一个相同类型的元素列表作为模板参数,所以我使用了一个向量,但我不确定如何使其工作在

#include <iostream>
#include <cstdint>
#include <vector>
template <uint8_t VAL>
void foo()
{
    std::cout << "__" << std::endl;
};
template <>
void foo<3>()
{
    std::cout << "OK" << std::endl;
};
int main()
{
    std::vector<uint8_t> v = { 2, 4, 5, 2, 3, 55 };
    for (auto &k : v) {
        foo<k>();
    }
    return (0);
}

编译器基本上抱怨k不是a constant expression,问题是我不知道如何修改它来实现这一点,我需要一些数据结构来迭代,所以我需要保留向量,我需要一个模板来简化我的生活,所以我看到的越多,我就越觉得被困在一个无限循环中。

您可以使用变量模板来摆脱实际将列表存储在向量中的情况,因此您只需将值直接传递给变量函数模板:

#include <iostream>
void print(int t) {
    static char const *s [] = { "__", "OK" };
    std::cout << s[t == 3];
}
void print() {}
template<typename... Args>
void print(int n, Args ... args) {
    print(n);
    print(args...);
}
int main() {
    print(2, 4, 5, 2, 3, 55);
}

结果:

________OK__

但是,正如您所看到的,这仍然需要在运行时计算等于3的值。我不太愿意说不能用模板专业化来完成,但至少我不知道如何完成,如果可能的话。

如果<here>所需的内容在编译时无法简单推导,则不应该使用模板。在这种情况下,k不是常量表达式,因此不能将其用作模板参数。

模板不是魔法锤。它们有很多用例,但你不能把它们完全用于所有事情。

在这个特定的代码片段中,foo应该定义为void foo(uint8_t)


是的,实际上我的问题是如何将向量转化为一组恒定的编译时值,真正的问题不是模板。

您可能可以使用可变模板来实现这一点。不使用矢量,而是直接在变量模板(foo<2, 4, 5, 2, 3, 55>)中使用积分常数。

我对它们不太感兴趣,所以这需要一段时间。

编辑:杰瑞打败了我。

如果您真的想要一种方法来迭代整数值的编译时常量列表:

#include <iostream>
#include <cstdint>
template <uint8_t VAL>
inline void foo()
{
    std::cout << "__" << std::endl;
}
template <>
void foo<3>()
{
    std::cout << "OK" << std::endl;
}
template <uint8_t... Values>
struct FooHelper {
  static void foo_all() {
  }
};
template <uint8_t First, uint8_t... Rest>
struct FooHelper<First, Rest...> {
  static void foo_all() {
    foo<First>();
    FooHelper<Rest...>::foo_all();
  }
};
template <uint8_t... Values>
void foo_all()
{
    FooHelper<Values...>::foo_all();
}
int main()
{
    foo_all<2, 4, 5, 2, 3, 55>();
}

尽管我真的没有看到它的用例。

编译器在编译时不可能推断出k的可能值,所以我看不出这是怎么回事?

不,这对非常量表达式不起作用。只是让它成为一个简单的老功能:

#include <iostream>
#include <cstdint>
#include <vector>
void foo(uint8_t VAL)
{
    if(VAL == 3)
        std::cout << "OK" << std::endl;
    else
        std::cout << "__" << std::endl;
};
int main()
{
    std::vector<uint8_t> v = { 2, 4, 5, 2, 3, 55 };
    for (auto &k : v) {
        foo(k);
    }
return (0);
}