具有不同亚型的参数方法

Parametric methods with different subtypes

本文关键字:参数 方法 亚型      更新时间:2023-10-16

今天在编程语言课中,我们在Java中看到了这种行为:

public class Es {
   ...
   <Y> Y choose(Y y1, Y y2){
         Y returnVal;
         if("some test"){ returnVal = y1;} else{ returnVal = y2;}
         return returnVal;
   }
}

主要:

Es c = new Es();
Integer i = 3;
Float f = (float) 4.5;
Number n = c.choose(i, f);

"令人难以置信的"是该方法必须在整数和float之间选择参数类型y并选择最近的超级类型,即数字。

我想在C 中重现它,但我被卡住了...

模板在不匹配时不要尝试调整类型。这就是为什么简单实现如下的原因:

template <class Y>
Y choose(Y y1, Y y2) {
    // ...
}

失败了以下错误:

main.cpp:8:5: fatal error: no matching function for call to 'choose'
    choose(1, 2.5f);
    ^~~~~~
main.cpp:3:3: note: candidate template ignored:
                    deduced conflicting types for parameter 'Y' ('int' vs. 'float')

您想做的是让函数模板两种类型,然后然后解析公共类型:

template <class Y1, class Y2>
auto choose(Y1 y1, Y2 y2) {
    using Y = std::common_type_t<Y1, Y2>;
    Y returnVal;
    if("some test") {
        returnVal = y1;
    } else {
        returnVal = y2;
    }
    return returnVal;
}

一个好主意是通过将类型的扣除额提升为签名来使功能对Sfinae友好:

template <class Y1, class Y2>
std::common_type_t<Y1, Y2> choose(Y1 y1, Y2 y2) {
    // Same as before
}

使用模板函数。与Java代码相同的C 代码实际上与Java代码非常相似:

template <typename Y>
Y choose(Y y1, Y y2) {
    Y returnVal;
    if("some test"){ returnVal = y1;} else{ returnVal = y2;}
    return returnVal;
}

您可以像在Java中那样称呼它 - 编译器将推断出正确的类型:

choose(1,2); //With two ints
choose("hi","bye"); //With two char*s.

注意:语义上,C 模板与Java Generics完全不同。JAVA通用物是使用类型擦除实现的 - JRE不知道运行时类型参数,而C 模板实际上每次将模板用于其他类型时创建单独的函数或类。看到此答案。

编辑:我误解了您的问题。如果不考虑,我认为C 没有您想要的行为。您必须明确指定两者都是超级型。