c++函数与带整型形参的模板
C++ function vs template with an integer parameter?
阅读Wikibook优化c++,在这一段有以下建议:
如果整数值在应用程序代码中是常量,但在库代码中是变量,则将其作为模板形参。
如果我有一个像
这样的函数void myfunction(int param)
{
switch(param)
{
case 1:
do_something_1();
break;
case 2:
do_something_2();
break;
...
case 100: // 100 is taken as example
do_something_100();
break;
}
}
用下面的替换方便吗?
template<int param> void myfunction()
{
switch(param)
{
case 1:
do_something_1();
break;
case 2:
do_something_2();
break;
...
case 100: // 100 is taken as example
do_something_100();
break;
}
}
还是完全没有必要?你能给我解释一下原因吗?
您所考虑的调整只有在编译时参数已知时才有效。在你的引言中,有一个关于应用程序代码的假设,这是你在编写库时不能做的。
如果你在应用程序代码中调用的函数曾经是
const int x = 3;
myfunction(1);
myfunction(2);
myfunction(x);
//etc...
它们可以重写如下:
const int x = 3;
myfunction<1>();
myfunction<2>();
myfunction<x>();
//etc...
但如果x
是一个变量,则不可能:
int x = ...; // unknown at compile-time!
myfunction<x>(); // will fail to compile!
如上所述,在某些情况下,在编写库时不应该对应用程序进行假设。有时候你想做的或者需要做的。让我们考虑这样一种情况:你希望应用程序使用一个常量,但是你不希望强迫这样做。
您希望优化,因为它将使用常量,但仍然允许使用变量。为此,我建议两个选项:
创建两个备选项,一个带模板参数,一个带函数参数。
内联函数,因此在编译应用程序代码时,编译器可以看到函数的定义,并且可以使用它来优化为单个
do_something_*()
调用,如果参数是常量。
注意,这两个选项都需要将函数的定义暴露给应用程序的代码。我倾向于使用第二个选项
这取决于你想如何使用myfunction
。例如,您的模板化函数不能与运行时声明的变量一起使用:
int dosomethingmaybe = 1;
dosomethingmaybe += 2;
myfunction< dosomethingmaybe >(); // <--- Error, you cannot instantiate a template with a non-constant variable
myfunction( dosomethingmaybe ); // <--- Will call `do_something_3();`, according to your code
当你可以在编译时提供一个不会在运行时更改的参数时,你可以使用模板。模板总是在编译时求值,因此它们的输入和输出在程序运行之前就固定了!
如果你知道有人可以提前修复输入并期望某个功能的输出,就制作一个模板版本。否则,常规函数运行时版本就可以了。
我怀疑您在实际情况中实际上会看到性能优势。如果调用是内联的,则这两种方法之间没有区别—只要在编译时参数是已知的(必须是),一个体面的编译器将在这两种情况下删除不必要的切换。唯一可以看到区别的情况是内联没有发生——在这种情况下,模板化方法允许删除开关,而另一种方法则不允许。然而,无论如何,在这种情况下,函数调用开销可能会使切换的成本相形见绌。
- C 字符串返回字符串的整数/双精度/长整型值
- 是什么导致了这种使用三进制而不是短整型的有符号int到无符号int转换
- 无法在 Arduino 中uint8_t数组转换为无符号长整型数组
- JNI 日期值转换问题,在C++中获取不同的长整型值
- 将长整型值打印为带有前导零的十六进制
- 为什么在传递长整型时调用具有两个双精度类型的参数的重载函数?
- 将整型常量映射到类型
- 将元组和整型实例合并到引用元组中
- 提升不良词法强制转换:将字符串转换为无符号长整型时,无法将源类型值解释为目标
- 为什么C++不允许两个同名的函数/类模板,区别仅在于非类型模板参数(整型)的类型?
- 将最小值整数转换为无符号长整型
- 如何将小端格式的QByteArray转换为无符号长整型
- 直接初始化无符号短整型的标准行为
- 无符号长整型和无符号 int 之间有什么区别,这 2 种类型应该如何在 c# 中封送?
- 无符号和有符号短整型的位宽
- 将整型转换为浮点型时检测溢出
- 环礁和(长整型)的区别?
- const整型模板形参的条件
- 如何使c++函数隐式地将整型数列表转换为矢量形参
- c++函数与带整型形参的模板