给出讨论here,这大致是关于让编译器在编译时计算if / else ...
#include <initializer_list>
template<typename U, typename ... T>
bool one_of(U&& u, T && ... t)
{
bool match = false;
(void)std::initializer_list<bool>{ (match = match || u == t)... };
return match;
}
int main(int argc, char** argv)
{
return one_of(argc, 1, 2, 3, 4, 5);
}
我已经在较旧的C ++领域工作了很长一段时间,并没有像我想的那样在现代C ++中发挥作用,所以...
有没有办法用例如编译时已知的字符串数组来完成上述操作?我更喜欢避免循环。以上对int / float类型的效果相当好,并且在上面的示例中在x86_64中生成3到5条指令。
在这个最简单的形式中,我想这个问题是关于如何将数组转换为模板化函数的参数列表。
编辑:应krzaq的要求
我想看看上面的内容,而不是one_of( argc, 1, 2, 3, 4, 5 )
我想要one_of( argc, array_of_compiletime_ints )
并将其归结为类似的代码并使其适用于除char之外的其他内容短/ INT /浮动/双
如果你看看任何一个神盾链接,你会发现它编译成很少的代码。
答案 0 :(得分:0)
尝试利用模板系统的图灵完整性是自90年代初以来的事情:):))
但是编译器通常礼貌但坚定,而且明智地拒绝深入到模板计算中,因为这意味着需要花费大量编译时间来非常缓慢地评估可以很容易地表达为更快运行时计算的方式:)
答案 1 :(得分:0)
问题中的示例(取自链接的博客文章)有些误导 - 它产生了错误的印象,即C ++ 11的新功能可以实现精彩的结果,而它只能说明现代编译器在优化代码方面有多好。鉴于输入数据在编译时是已知的,即使循环可以被优化到相同的效果。
这是请求的one_of( argc, array_of_compiletime_ints )
函数,但不是没有循环:
template<typename U, typename T, int N>
bool one_of(U&& u, T (&a)[N])
{
for ( int i = 0; i < N; ++i )
if (a[i] == u)
return true;
return false;
}
int main(int argc, char** argv)
{
int a[] = {1, 2, 3, 4, 5};
return one_of(argc, a);
}
clang 3.9.0将此优化级别-O3编译为:
main: # @main
dec edi
cmp edi, 5
sbb eax, eax
and eax, 1
ret
检查at godbolt。