如何确保模板函数的参数与另一个参数

时间:2017-09-03 21:56:49

标签: c++ templates

让我说我有一个函数,我想传递给表单的另一个函数。

auto f = [](double x) -> double {
    // ...
    return 2.0;
};

或此形式:

double f(double x) {
    // ...
    return 2.0;
};

我想要一个模板函数来取f,另一个参数将用于调用f。

类似的东西:

template <typename F, typename T>
T use_function(F func, T t)
{
    return func(t);
};

但我想强制说T与f的返回类型具有相同的类型。我的主要问题是当我调用使用函数时:

use_function(f, 5);

T的类型变为int。我正在做数学的东西,这给了我错误的答案使用整数。因此,一种解决方案是以某种方式强制执行浮点类型......

我正在考虑将此作为解决方案使用:

template <typename F, typename T>
auto use_function(F func, T temp) -> decltype(func(temp))
{
    decltype(func(temp)) t = temp; // This will convert to double if temp was an int....
}

你怎么看?

2 个答案:

答案 0 :(得分:0)

自动返回类型和参数的完美转发将允许以最佳效率方式将参数的隐式转换加倍。

#include <iostream>
#include <iomanip>

auto f = [](double x) -> double {
    // ...
    return 2.0;
};

double f2(double x) {
    // ...
    return 2.0;
};

struct doubly_thing
{
    operator double() const {
        return 6;
    }
};

template <typename F, typename T>
auto use_function(F func, T&& t)
{
    return func(std::forward<T>(t));  // optimal implicit conversion here
};

int main()
{
    std::cout << std::setprecision(4) << use_function(f, 5) << std::endl;
    std::cout << std::setprecision(4) << use_function(f2, 5) << std::endl;
    std::cout << std::setprecision(4) << use_function(f2, doubly_thing()) << std::endl;
}

答案 1 :(得分:0)

template <class F, class T, class R=std::result_of_t<F&(T&)>>
R use_function(F func, T t_in) {
  static_assert(std::is_same<R, std::result_of_t<F&(R&)>>::value, "type drift error" );
  R t = std::forward<T>(t_in);
  return func(t);
}

这首先根据参数推断出f的返回类型。然后它会仔细检查如果将参数转换为返回类型,则仍然会使用相同的类型。

它将此返回类型存储在R