【问题标题】:Class for overloaded method accepts template and base class - How to default a certain method?重载方法的类接受模板和基类 - 如何默认某个方法?
【发布时间】:2018-03-25 02:54:40
【问题描述】:

我正在使用奇怪的循环模板模式来解决 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&amp;)时,方法默认为 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

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

【问题讨论】:

  • 我不确定我是否理解您的问题,但据我所知,输出没有错误
  • 嘿,我的意思是上述方法是通过引用而不是通过值,现在问题应该有意义了。

标签: c++ templates generics inheritance


【解决方案1】:

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

您没有收到警告,因为您为函数提供了base&amp;,而只有一个重载需要base&amp;。如果您希望此特定代码调用 runderiv&amp; 重载,则需要将 base&amp; 重载更改为以下内容:

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 失败的情况下,遍历指针类型可以防止异常。

【讨论】:

  • 嘿抱歉,我的意思是这些方法是参考而不是价值,现在问题应该有意义了。
  • 我会更新我的答案,但编译器仍然会看到一个函数输出 base&amp; 类型并选择函数的 base&amp; 重载。如果您想让run 在这种情况下对deriv&amp; 对象采取不同的行为,那么您将需要执行dynamic_cast 并查看它是否失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多