代码之家  ›  专栏  ›  技术社区  ›  Joseph Franciscus

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

  •  2
  • Joseph Franciscus  · 技术社区  · 9 年前

    我正在使用奇怪的递归模板模式来解决C++中的一个问题。 在某些情况下,使用相同的方法,我需要返回一个子类或基类。

    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 回复  |  直到 9 年前
        1
  •  1
  •   Kyle A    9 年前

    alter 返回类型 base& . 这意味着声明 bar.run(bar.alter(foo)); 将评估 bar.alter(foo) ,返回对的引用 foo 演员阵容 基本(&A); . 然后 bar.run() 被称为 基本(&A); 参考

    您没有收到警告,因为您给了函数一个 只需要一次过载 基本(&A); . 如果您希望此特定代码调用 deriv& 过载 run ,您需要更改 基本(&A); 过载如下:

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

    这将检查传入的引用是否确实是对的引用 deriv ,并调用正确的 跑 需要时。注意,遍历指针类型可以防止 dynamic_cast