我正在使用奇怪的重复模板模式来解决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
?
另外我认为编译器应该给出一个定义不明确的警告(因为它基本上有两个接受相同类型的方法)。
答案 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
失败的情况下,通过指针类型可以防止异常。