重载方法的类接受模板和基类 - 如何默认某个方法?

时间:2017-10-13 03:15:33

标签: c++ templates generics inheritance

我正在使用奇怪的重复模板模式来解决C ++中的问题。 在使用相同方法的某些实例中,我需要返回子类或基类。

因此方法dec类似于

base& get() {
 return base_ref || deriv_ref; //depends on impl
}

虽然我有其他方法,如

template <typename deriv> 
class base {

 void run(deriv& d) {//deriv specific method/derived class/}
 void run(base& b)  { //base specific method// }
}

但是每当我返回derived class(重新编号为base&)时,方法默认为base类实现,如下所示。

template<typename d>
struct base {

    void run(d& type) {
        std::cout << "deriv " << std::endl;
    }
    void run(base& type) {
        std::cout << "base" << std::endl;
    }
    base& alter(d& der) {
        return der;
    }
    d& no_alt(d& der) {
        return der;
    }
};
struct deriv : public base<deriv> {

};
int main() {
    deriv foo;
    base<deriv> bar;
    bar.run(foo);           //prints deriv
    bar.run(bar);           //print base
    bar.run(bar.alter(foo));//print base (Need this to print deriv)
    bar.run(bar.no_alt(foo));//print deriv

}

如何在这些情况下将方法默认为derived_methods

另外我认为编译器应该给出一个定义不明确的警告(因为它基本上有两个接受相同类型的方法)。

1 个答案:

答案 0 :(得分:1)

alter会返回base&类型。这意味着语句bar.run(bar.alter(foo));将评估bar.alter(foo),该foo会将base&的引用返回为bar.run()。然后,使用base&引用调用base&

您没有收到警告,因为您为函数提供了base&,只有一次重载需要deriv&。如果您希望此特定代码调用run的{​​{1}}重载,则需要将base&重载更改为以下内容:

void run(base& type) {
    deriv* derivTest = dynamic_cast<deriv*>(&type);
    if( derivTest != nullptr )
        run(*derivTest);
    else
        std::cout << "base" << std::endl;
}

检查传入的引用是否真的是对deriv的引用,并在需要时调用正确的run。请注意,在dynamic_cast失败的情况下,通过指针类型可以防止异常。