[英]Passing different types of parameters to a function template
考虑这个模板:
template<typename t>
t add(t a, t b) {
return a+b;
}
如何传递不同类型的参数,以便返回值为:
int
如果两个参数都是int
类型。
float
如果参数中的一个是类型的float
。
float
如果两个参数的类型的float
。
我也尝试过为模板设置多个参数:
template<typename t, typename c>
使用它们作为函数参数,因此它们可以是不同的( t add(ta, cb)
)但是我t add(ta, cb)
是我如何根据函数的类型(int,float,double等)来改变在返回类型?
使用自动类型推导(从c ++ 14开始):
template<typename t, typename u>
auto add(t a, u b) {
return a+b;
}
你想要的是std::common_type
:
template<typename T0, typename T1>
typename std::common_type<T0, T1>::type add(T0 a, T1 b) {
return a+b;
}
文件说明:
对于算术类型,可以将公共类型视为(可能是混合模式)算术表达式的类型,例如T0()+ T1()+ ... + Tn()。
但是,正如@ Jarod42在评论中指出的那样,这只是一个视图,在某些情况下可能是错误的:例如, std::common_type<char, char>::type
是char
而算术表达式char() + char()
产生int
。
更完整的实现可以明确地转换结果以消除上述情况中的可能警告:
template<typename T0, typename T1, typename R = std::common_type_t<T0, T1>>
R add(T0 a, T1 b) {
return static_cast<R>(a+b);
}
这里std::common_type
默认用于返回类型,但由于它是模板参数,因此在使用该函数时可以指定不同的类型(在更复杂的用例中可能有用):
char a = 1, b = 2;
add<decltype(a), decltype(b), int>(a, b);
使用std::conditional
和std::is_same
,@ Jarod42在注释中提出的更完整的解决方案允许将模板R
作为第一个参数,并保持对a
和b
自动推导:
template <typename R, typename T0, typename T1>
using ResType = std::conditional_t<
std::is_same<void, R>::value,
std::common_type_t<T0, T1>, // default
R // R was explicitly specified: use it
>;
template <typename R = void, typename T0, typename T1>
ResType<R, T0, T1> add(T0 a, T1 b)
{
return static_cast<ResType<R, T0, T1>>(a + b);
}
用法:
char a = 1, b = 2;
add(a, b); // returns char
add<int>(a, b); // returns int
在c ++ 11及std::common_type
,您可以使用std::common_type
template<typename T1, typename T2>
auto add(T1 a, T2 b) -> typename std::common_type<T1, T2>::type {
return a + b;
}
如同在Piotr的回答中一样,它将起到整体促销的作用,与仅仅进行auto
类型演绎没有多大区别。 但是,如果您尝试将自定义类型作为参数传递,例如std::complex
类,它将真正开始闪耀。
我宁愿保留标准所强加的整体推广类型,所以也许这应该包含在另一个特征中。
template<typename T1, typename T2>
class AdditionTraits {
using common_t = typename std::common_type<T1, T2>::type;
constexpr static bool is_char = std::is_same<common_t, char>::value;
public:
using type = typename std::conditional<is_char, int, common_t>::type;
};
template<typename T1, typename T2>
auto add(T1 a, T2 b) -> typename AdditionTraits <T1, T2>::type {
return a + b;
}
您可以看到它将char
添加到int
,正如标准的促销规则那样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.