C++ 用条件调用模板函数
给定具有类型模板的函数:C++ 用条件调用模板函数,c++,templates,C++,Templates,给定具有类型模板的函数: template<typename TYPEA, typename TYPEB, typename TYPEC> void foo (TYPEA a, TYPEB b, TYPEC c) { ...; } 模板 void foo(类型a、类型b、类型c){…;} 然后我希望通过如下方法调用此函数: int main (void) { int ta = 32; int tb = 64; int tc = 32; fl
template<typename TYPEA, typename TYPEB, typename TYPEC>
void foo (TYPEA a, TYPEB b, TYPEC c) { ...; }
模板
void foo(类型a、类型b、类型c){…;}
然后我希望通过如下方法调用此函数:
int main (void) {
int ta = 32;
int tb = 64;
int tc = 32;
float *array_a;
double *array_b;
float *array_c;
foo<(ta == 32 ? float : double), (tb == 32 ? float : double), (tc == 32 ? float : double)>(array_a, array_b, array_c);
return 0;
}
int main(无效){
int-ta=32;
int tb=64;
int tc=32;
浮点*数组_a;
双*阵列;
浮点*数组_c;
foo(数组a、数组b、数组c);
返回0;
}
当然,这段代码会导致编译错误
然而,我只是想知道是否有一种方便的方法来检查ta、tb和tc的值并相应地调用函数foo 正如Cameron在评论中指出的,模板参数必须在编译时已知。而且,类型不是C++中的第一个值,所以不能像表达式一样从表达式中返回它们。 查看您的代码,您可能只需将数组传递到
foo
,即可获得所需的内容,如下所示:
float *array_a;
double *array_b;
float *array_c;
foo(array_a, array_b, array_c);
由于
array\u a
、array\u b
和array\u c
的类型在编译时是已知的,并且foo
将每种类型声明为单独的类型参数,编译器将创建一个函数foo(float*,double*,float*)
,这似乎是您试图产生的效果。首先,根据变量值和条件运算符选择用于实例化模板的类型在语法上是错误的。该语言不允许该方法选择类型
其次,您可以让编译器推断类型。您只需使用:
foo(array_a, array_b, array_c);
编译器将TYPEA
推断为float*
,TYPEB
推断为double*
,TYPEC
推断为float*
使用
ta
和朋友的值在运行时可能会更改。编译时必须知道模板参数。t的常量不够,不能使用条件运算符返回这样的类型。如果您可以设置t的常数,则需要一些模板元编程,以便能够根据constexpr
数量选择类型。如果它们必须保持可变,那么您必须将条件检查拉到对foo的调用之外,并在每个嵌套的条件分支中放置8个foo调用。这只有在编译时已知ta、tb和tc时才可能(如constepr
s),即使这样,您也需要使用复杂的模板元编程技术。@Wei Fan Chiang:您的问题与调用函数几乎没有关系。您的问题是关于模板的实例化。模板实例化是一个编译时过程。它不可能依赖于运行时参数,无论您如何分割它。您试图解决的问题与模板无关。
foo<float, double, float>(array_a, array_b, array_c);
template <int N> struct TYPE_Chooser { using type = double; };
template <> struct TYPE_Chooser<32> { using type = float; };
int main ()
{
const int ta = 32;
const int tb = 64;
const int tc = 32;
using typea = typename TYPE_Chooser<ta>::type;
using typeb = typename TYPE_Chooser<tb>::type;
using typec = typename TYPE_Chooser<tc>::type;
foo<typea, typeb, typec>(10, 20, 30);
return 0;
}