2017-09-03 45 views
0

假设我有一个函数要传递给窗体的另一个函数。如何确保模板函数的参数与另一个参数的参数匹配

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

或这种形式:

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

我希望有一个模板函数取女,与将用于调用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.... 
} 

,你怎么看待这个问题?

+0

充分暴露于C++ 17,充分利用'auto'关键字。所有你需要做的是:'template auto use_function(F func,T t) { return func(t); }'。即使'T'是'int',如果'func'返回一个'double',这就是你会得到的。 –

+0

为了确保它,我经常在一个'std :: function'对象中包含仿函数。如果有任何不匹配,它应该给编译时错误。 – Vivick

+0

@Vivick你可以输入一个简单的例子。不知道你的意思 – CptLightning

回答

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

OP意味着* more *不仅仅是函数调用正在进行中。 – Yakk

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中。