C++ C++;带整数参数的函数与模板?
在阅读维基百科时,有以下建议: 如果整数值在应用程序代码中是常量,但在库代码中是变量,请将其设置为模板参数 如果我有一个函数,比如C++ C++;带整数参数的函数与模板?,c++,function,templates,C++,Function,Templates,在阅读维基百科时,有以下建议: 如果整数值在应用程序代码中是常量,但在库代码中是变量,请将其设置为模板参数 如果我有一个函数,比如 void myfunction(int param) { switch(param) { case 1: do_something_1(); break; case 2: do_something_2(); b
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;
}
}
模板void myfunction()
{
开关(参数)
{
案例1:
做点什么;
打破
案例2:
做点什么;
打破
...
以案例100://100为例
做点什么;
打破
}
}
还是完全没有必要?你能给我解释一下原因吗?只有在编译时知道参数的情况下,你想的调整才有效。在您的引用中,有一个关于应用程序代码的假设,您在编写库时不能这样做 如果您的函数在应用程序代码中调用
const int x = 3;
myfunction(1);
myfunction(2);
myfunction(x);
//etc...
它们可以重写如下
const int x = 3;
myfunction<1>();
myfunction<2>();
myfunction<x>();
//etc...
如上所述,在编写库时,有些情况下不应该对应用程序进行假设。有时候你想做或需要做。让我们考虑一下你希望应用程序使用常量的情况,但是你不想强迫它这样做。
您希望优化,因为它将使用常量,但仍允许使用变量。为此,我建议两种选择:
- 做两个选择,一个带模板参数,一个带函数参数
- 内联函数,因此在编译应用程序代码时,编译器会看到函数的定义,如果参数为常量,则可以使用函数定义将其优化为单个
调用do\u 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
int dosomethingmaybe=1;
dosomethingmaybe+=2;
myfunction();// 我怀疑您是否真的会在实际情况中看到性能优势。如果调用是内联的,那么这两种方法之间没有区别——只要参数在编译时是已知的(必须是已知的),一个好的编译器将在这两种情况下删除不必要的开关。唯一可以看到差异的情况是没有内联——在这种情况下,模板化方法将允许删除开关,而另一种方法则不会。但是,无论如何,在这种情况下,函数调用开销可能会使开关的成本相形见绌。如果编译器在编译时知道“param”的值,它可能会完全删除开关,以保留可以访问的唯一代码。这不是很有用。如果它是一个常量,你让编译器内联代码,我想结果是一样的。你提到的那一页已经给出了原因。如果整数值在应用程序代码中是常量,但在库代码中是变量,则将其作为模板参数。模板和内联函数都需要公开函数定义(除非你胆敢进入现已弃用且从未真正支持C++03导出模板的地下城),这就是我在最后一句中所说的(注意“还”)。我会重写一下。
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