模板类型推断可以考虑原始操作类型转换吗?

时间:2018-04-02 06:48:34

标签: c++ c++11 templates c++14 template-meta-programming

模板似乎无法输入 - 推断原始操作的结果。例如,以下内容无法推断出R:

template<typename A, typename B, typename R>
R addNumbers(A x, B y){
    return x + y;
}
main(){
    addNumbers(1.0f, 1);
}

即使明确float + int = float

在任何版本的C ++中,有没有办法让推理在不明确指定的情况下考虑这些信息?

3 个答案:

答案 0 :(得分:5)

调用函数时的模板参数推导无法查看函数体;它只是试图使函数的参数类型与参数类型相同,并且任何不能通过这种方式推导出的模板参数都不会受到影响。您需要一种基于函数体中的return语句的演绎形式。这由C ++ 14中的auto提供:

template<typename A, typename B>
auto addNumbers(A x, B y){
    return x + y;
}

答案 1 :(得分:1)

功能过载扣除,无论是否考虑模板,都不会也不能考虑返回类型。返回类型不是函数签名的一部分。 Deduction仅考虑调用的参数是否匹配各种函数声明的参数。以下内容将匹配任何A和B.如果定义了operator+ (A, B),则返回类型将是它返回的任何内容。如果未定义operator+ (A, B),编译器将抛出错误。

template<typename A, typename B>
auto addNumbers(A x, B y){
    return x + y;
}
int main(){
    addNumbers(1.0f, 1);
}

答案 2 :(得分:1)

decltype是C ++ 11中最好的补充之一。 阅读更多相关信息:http://en.cppreference.com/w/cpp/language/decltype

基于C ++ 11的解决方案(使用编译器标记-std=c++11

template<typename A, typename B>
auto addNumbers(A const & x, B const & y) -> decltype(x + y)
{
    return x + y;
}

decltype的最佳部分,你几乎可以在其中编写任何表达式,并且它将在编译时进行评估。

在上面的例子中,我们要求编译器通过仅仅评估它们的类型来声明函数的返回类型,与表达式x + y的返回类型相同。

基于C ++ 14的解决方案(不需要decltype,使用编译器标志-std=c++14

template<typename A, typename B>
auto addNumbers(A const & x, B const & y)
{
    return x + y;
}

用法:

auto ans = addNumbers(1.0f, 1); // ans is deduced to be float