给定一个带有类型模板的函数:
template<typename TYPEA, typename TYPEB, typename TYPEC>
void foo (TYPEA a, TYPEB b, TYPEC 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;
}
当然,这段代码导致编译错误......
但是,我只是想知道是否有一种方便的方法可以相应地检查ta,tb&#39; s和tc的值以及调用函数foo ...
答案 0 :(得分:2)
首先,选择用于基于变量值实例化模板的类型,条件运算符在语法上是错误的。该语言不允许该方法选择类型。
其次,您可以让编译器推断出类型。你可以使用:
foo(array_a, array_b, array_c);
编译器会将TYPEA
推断为float*
,TYPEB
推导为double*
,TYPEC
推导为float*
。
使用
foo<float, double, float>(array_a, array_b, array_c);
不正确,因为用于实例化模板的类型与参数类型不匹配。
第三,如果您希望能够基于值派生类型,则值必须为const
或constexpr
。您可以使用:
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;
}
答案 1 :(得分:1)
正如Cameron在评论中指出的那样,模板参数必须在编译时知道。此外,类型不是C ++中的第一类值,因此您不能像在尝试时那样将它们作为表达式返回。
查看您的代码,看起来只需将数组传递给foo
即可获得所需内容,如下所示:
float *array_a;
double *array_b;
float *array_c;
foo(array_a, array_b, array_c);
由于array_a
,array_b
和array_c
的类型在编译时已知,foo
将每个类型声明为单独的类型参数,编译器将创建一个函数foo(float*, double*, float*)
,这似乎是你试图产生的效果。