【发布时间】:2015-11-21 07:29:33
【问题描述】:
给定
class A {
public:
virtual int foo (int) const = 0;
virtual void bar (char, double) const = 0;
};
class B : public A {
virtual int foo (int) const {std::cout << "B::foo() called.\n"; return 3;}
virtual void bar () const {std::cout << "B::bar() called.\n";}
};
class C : public B {
virtual int foo (int) const {std::cout << "C::foo() called.\n"; return 8;}
virtual void bar (char, double) const {std::cout << "C::bar() called.\n";}
};
我想将foo 和bar(以及A 的其他虚函数)放入函数的模板族中。到目前为止,这是我想出的:
#include <iostream>
enum Enum {Foo, Bar};
template <Enum> struct EnumTraits;
template <> struct EnumTraits<Foo> { using return_type = int; };
template <> struct EnumTraits<Bar> { using return_type = void; };
class A {
template <Enum> class Execute;
public:
virtual int foo (int) const = 0;
virtual void bar (char, double) const = 0;
template <Enum E, typename... Args>
typename EnumTraits<E>::return_type execute(Args&&... args) const {
return Execute<E>(this)(std::forward<Args>(args)...);
}
};
template <>
class A::Execute<Foo> {
const A* a;
public:
Execute (const A* a_) : a(a_) {}
template <typename... Args>
int operator()(Args&&... args) const {return a->foo(std::forward<Args>(args)...);}
};
template <>
class A::Execute<Bar> {
const A* a;
public:
Execute (const A* a_) : a(a_) {}
template <typename... Args>
void operator()(Args&&... args) const {a->bar(std::forward<Args>(args)...);}
};
class B : public A {
virtual int foo (int) const {std::cout << "B::foo() called.\n"; return 3;}
virtual void bar () const {std::cout << "B::bar() called.\n";}
};
class C : public B {
virtual int foo (int) const {std::cout << "C::foo() called.\n"; return 8;}
virtual void bar (char, double) const {std::cout << "C::bar() called.\n";}
};
int main() {
A* c = new C;
int n = c->foo(5); // C::foo() called.
c->bar(3, 'c'); // C::bar() called.
n = c->execute<Foo>(5); // C::foo() called.
c->execute<Bar>(3, 'c'); // C::bar() called.
}
但特化 A::Execute<Foo> 和 A::Execute<Bar> 看起来几乎相同,理想情况下应该保持非特化(特别是如果有许多其他虚函数而不是 foo 和 bar)。写成这样:
template <Enum N>
class A::Execute {
const A* a;
public:
Execute (const A* a_) : a(a_) {}
template <typename... Args>
int operator()(Args&&... args) const {return a->???(std::forward<Args>(args)...);}
};
如何填写???部分?理想情况下,我希望使用已经存在的 EnumTraits 类。
【问题讨论】:
-
这是一项智力练习吗?您是否正在尝试寻找真正的设计问题的答案?
-
我想以通用方式在其他地方使用模板系列。真的很有帮助。
标签: c++ function templates c++11 virtual