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

时间:2016-12-25 10:10:31

标签: c++ function templates

考虑这个模板:

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(t a, c b))但是我无法解决的问题是如何更改函数的类型(int,float,double等) 。)取决于退货类型?

3 个答案:

答案 0 :(得分:12)

使用auto类型推导(自c ++ 14起):

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

答案 1 :(得分:12)

你想要的是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>::typechar而算术表达式{{1}收益率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

使用std::conditionalstd::is_same,@ Jarod42在评论中提出的更完整的解决方案允许将模板char a = 1, b = 2; add<decltype(a), decltype(b), int>(a, b); 作为第一个参数,并保留{{1}的自动扣除}和R

a

用法:

b

答案 2 :(得分:6)

在c ++ 11及更高版本中,您可以使用std::common_type

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

它将像整体促销一样发挥作用,与auto类型扣除一样,与Piotr的答案完全不同。但是,如果您尝试将自定义类型作为参数传递,例如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;
}

can see charint添加到auto cmp = [](const auto& lhs, const auto& rhs) { return lhs[0] < rhs[0]; } auto minIt = std::min_element(mySol.begin(), mySol.end(), cmp); auto eqToMin = [&](const auto& value) { return (*minIt)[0] == value[0]; } for (auto it = minIt; it != mySol.end(); it = std::find_if(it + 1, mySol.end(), eqToMin)) { std::cout << (*it)[1] << std::endl; } 中,与标准促销规则相同。