如何将矢量元素提供给模板
Posted
技术标签:
【中文标题】如何将矢量元素提供给模板【英文标题】:How to feed vector elements to a template 【发布时间】:2013-07-21 06:28:07 【问题描述】:我需要使用与模板参数相同类型的元素列表,所以我使用的是向量,但我不知道如何进行这项工作
#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
,问题是我不知道如何修改它以使其工作,我需要一些数据结构来迭代,所以我需要保留矢量,我需要一个模板来简化我的生活,所以我越看这个越觉得自己陷入了无限循环。
【问题讨论】:
不,这不是模板的用例。这是if (i == 3) cout << "OK";
的用例。
@H2CO3 你到底是什么意思?您可以模板化一个数值,这是肯定的,<3>
的重载只是为了检查模板调用中的某些内容。我需要一个数值模板。
@userXXX 我知道你可以使用 integer(不是任何数字)作为模板参数。虽然不是变量,但只是一个编译时常量。我的意思是我没有看到模板的必要性。这很可能是一个 XY 问题。
模板必须在编译时解析。这意味着您用作模板参数的任何内容都必须是编译时常量。这不仅意味着该值是在编译时设置的,而且它在语法上用作常量,而不仅仅是普通变量的值(就像您在此处所做的那样)。
@JerryCoffin 是的,事实上我的问题是如何将该向量转换为恒定编译时间的值集,真正的问题与模板无关。
【参考方案1】:
您可以使用可变参数模板来避免将列表实际存储在向量中,因此您只需将值直接传递给变量函数模板:
#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
的相等性。我不敢说它不能用模板专业化来完成,但至少我不知道如何如果可能的话。
【讨论】:
【参考方案2】:如果无法在编译时间上轻松推断出需要进行的<here>
,则不应使用模板。在这种情况下,k
不是常量表达式,因此您不能将其用作模板参数。
模板不是魔锤。它们有很多用例,但您不能绝对将它们用于所有事情。
在这个特定的 sn-p 代码中,foo
应定义为 void foo(uint8_t)
。
是的,事实上我的问题是如何将该向量转换为恒定编译时间的一组值,真正的问题与模板无关。
您也许可以使用可变参数模板来实现这一点。您可以直接在可变参数模板 (foo<2, 4, 5, 2, 3, 55>
) 中使用整数常量,而不是使用向量。
我对它们不是很感兴趣,所以这需要一段时间。
编辑:杰瑞打败了我。
【讨论】:
但我可以轻松地重载模板来修改单个值的行为,但我无法使用您建议的其他解决方案来做到这一点。 根本不可能使用运行时值作为模板参数。模板是编译时特性。因此需要常量表达式。【参考方案3】:如果您真的想要一种方法来迭代整数值的编译时常量列表:
#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>();
虽然老实说我没有看到它的用例。
【讨论】:
【参考方案4】:编译器无法在编译时推断 k 的可能值,所以我看不出这是如何工作的?
【讨论】:
这就是我需要解决的问题,我通常不会对已经工作的事情提出问题:D【参考方案5】:不,这不适用于非常量表达式。让它成为一个普通的旧函数:
#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);
【讨论】:
以上是关于如何将矢量元素提供给模板的主要内容,如果未能解决你的问题,请参考以下文章