简体   繁体   English

将不同类型的参数传递给函数模板

[英]Passing different types of parameters to a function template

Consider this template: 考虑这个模板:

template<typename t>
t add(t a, t b) {
    return a+b;
}

How can I pass different types of parameters so the return value will be: 如何传递不同类型的参数,以便返回值为:

  • int if both parameters are of type int . int如果两个参数都是int类型。

  • float if one of the parameters is of type float . float如果参数中的一个是类型的float

  • float if both parameters are of type float . float如果两个参数的类型的float

I've also tried having multiple parameters for the template: 我也尝试过为模板设置多个参数:

template<typename t, typename c>

using them for the function parameters so they can be different ( t add(ta, cb) ) but what I can't wrap my head around is how can I change the type of function (int, float, double, etc.) depending on the return type? 使用它们作为函数参数,因此它们可以是不同的( t add(ta, cb) )但是我t add(ta, cb)是我如何根据函数的类型(int,float,double等)来改变在返回类型?

Use auto type deduction (since c++14): 使用自动类型推导(从c ++ 14开始):

template<typename t, typename u>
    auto add(t a, u b) {
        return a+b;
    }

What you want is std::common_type : 你想要的是std::common_type

template<typename T0, typename T1>
typename std::common_type<T0, T1>::type add(T0 a, T1 b) {
    return a+b;
}

The documentation states: 文件说明:

For arithmetic types, the common type may be viewed as the type of the (possibly mixed-mode) arithmetic expression such as T0() + T1() + ... + Tn(). 对于算术类型,可以将公共类型视为(可能是混合模式)算术表达式的类型,例如T0()+ T1()+ ... + Tn()。

But, as pointed by @Jarod42 in the comments, this is just a view, and may be wrong in some cases: for example, std::common_type<char, char>::type is char whereas the arithmetic expression char() + char() yields int . 但是,正如@ Jarod42在评论中指出的那样,这只是一个视图,在某些情况下可能是错误的:例如, std::common_type<char, char>::typechar而算术表达式char() + char()产生int


A more complete implementation may explicitly cast the result to remove possible warnings in the cases cited above: 更完整的实现可以明确地转换结果以消除上述情况中的可能警告:

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);
}

Here std::common_type is used by default for return type, but since it is a template parameter, you may specify a different type when using the function (may be useful in more complex use cases): 这里std::common_type默认用于返回类型,但由于它是模板参数,因此在使用该函数时可以指定不同的类型(在更复杂的用例中可能有用):

char a = 1, b = 2;
add<decltype(a), decltype(b), int>(a, b);

Using std::conditional and std::is_same , an even more complete solution proposed by @Jarod42 in the comments allows to have template R as first parameter, and keep automatic deduction for a and b : 使用std::conditionalstd::is_same ,@ Jarod42在注释中提出的更完整的解决方案允许将模板R作为第一个参数,并保持对ab自动推导:

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);
}

Usage: 用法:

char a = 1, b = 2;
add(a, b);       // returns char
add<int>(a, b);  // returns int

In c++11 and onward, you can use std::common_type 在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;
}

It will work as if integral promotions are happening, not much different than just doing auto type deduction, as in Piotr 's answer. 如同在Piotr的回答中一样,它将起到整体促销的作用,与仅仅进行auto类型演绎没有多大区别。 But it will really start to shine if you try to pass custom types as parameters, such as std::complex classes. 但是,如果您尝试将自定义类型作为参数传递,例如std::complex类,它将真正开始闪耀。


I'd prefer to preserve the integral promotion types that the standard imposes, so perhaps this should be wrapped in another trait. 我宁愿保留标准所强加的整体推广类型,所以也许这应该包含在另一个特征中。

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;
}

You can see it adds char s into an int , as the standard promotion rules do. 可以看到它将char添加到int ,正如标准的促销规则那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM