假设层次结构的所有类都实现了模板成员函数g
。所有类共享调用此模板的另外两个函数f1
和f2
的相同实现:
struct A {
virtual void f1() {
g(5);
}
virtual void f2() {
g(5.5);
}
private:
template <typename T> void g(T) {std::cout << "In A" << std::endl;}
};
struct B: A {
// Can I get rid of this duplicate code?
virtual void f1() {
g(5);
}
virtual void f2() {
g(5.5);
}
private:
template <typename T> void g(T) {std::cout << "In B" << std::endl;}
};
struct C: A {
// Can I get rid of this duplicate code?
virtual void f1() {
g(5);
}
virtual void f2() {
g(5.5);
}
private:
template <typename T> void g(T) {std::cout << "In C" << std::endl;}
};
int main()
{
B b;
A &a = b;
a.f1();
return 0;
}
由于f1
和f2
的实现在所有类中都是相同的,我如何摆脱重复的代码,并且main
中的多态调用仍然按预期工作(即产生输出“在B中”?
答案 0 :(得分:3)
请注意f1
,f2
和A
中B
和C
的实现 不相同。我们将其限制为f1
s。一个调用名为::A::g<int>
的函数,另一个调用名为::B::g<int>
的函数,第三个调用名为::C::g<int>
的函数。他们很远相同。
你能做的最好的就是CRTP式的基础:
template <class Derived>
struct DelegateToG : public A
{
void f1() override
{
static_cast<Derived*>(this)->g(5);
}
void f2() override
{
static_cast<Derived*>(this)->g(5.5);
}
};
class B : public DelegateToG<B>
{
friend DelegateToG<B>;
private:
template <class T> void g(T) { /*...*/ }
};
class C : public DelegateToG<C>
{
friend DelegateToG<C>;
private:
template <class T> void g(T) { /*...*/ }
};
答案 1 :(得分:1)
您可以将模板函数使用的类特定事物分解出来,例如(在您的示例中)类名:
#include <iostream>
using namespace std;
class A
{
private:
virtual auto classname() const -> char const* { return "A"; }
protected:
template <typename T> void g(T) {cout << "In " << classname() << endl;}
public:
virtual void f1() { g(5); }
virtual void f2() { g(5.5); }
};
class B
: public A
{
private:
auto classname() const -> char const* override { return "B"; }
};
class C
: public A
{
private:
auto classname() const -> char const* override { return "C"; }
};
auto main()
-> int
{ static_cast<A&&>( B() ).f1(); }