在Stroustrup的 C ++编程语言(第4版)中,第27.4.2节显示了一种技术,以便线性化"钻石类层次结构,以避免虚拟基类的开销。他从真实项目(Pivot code analyzer tool):
开始钻石图案
线性版本绘制为:
和
代码大纲是:
namespace ipr {
struct Node { ... };
struct Expr : Node { ... };
struct Stmt : Expr { ... };
struct Decl : Stmt { ... };
struct Var : Decl { ... };
namespace impl {
template<class T> struct Node : T { ... };
template<class T> struct Expr : Node<T> { ... };
template<class S> struct Stmt : S { ... };
template<class D> struct Decl : Stmt<Expr<D>> { ... };
struct Var : Decl<ipr::Var> { ... };
}
}
我对不规则的结构感到困惑。基于最初的描述,我期待impl
看起来像:
namespace impl {
template<class T> struct Node : T { ... };
template<class T> struct Expr : Node<T> { ... };
template<class S> struct Stmt : Expr<S> { ... };
template<class D> struct Decl : Stmt<D> { ... };
struct Var : Decl<ipr::Var> { ... };
}
我认为这些类的完整图表是:
我的问题是,为什么不要&#34;内部&#34;三个impl
模板类具有并行形式,如我的代码版本?
答案 0 :(得分:2)
我最好的猜测来自查看有{/ 3>的actual Pivot code
template<class D> struct Decl : Stmt<Node<D>> { ... };
而不是Stroustrup的
template<class D> struct Decl : Stmt<Expr<D>> { ... };
这表明impl::Stmt
并不一定来自impl::Expr
,就像在原始钻石图中一样(尽管它仍然来自界面ipr::Expr
)。它并非来自impl::Expr
和Decl
的{{1}},但它适用于其他实现类,例如Var
:
impl::For
我不确定为什么Stroustrup没有解释这种不规则性。也许他认为他通过将struct For : Stmt<Expr<ipr::For> > { ... }
更改为Stmt<Node>
来删除它,或者可能根本没有更改它(也就是说,代码在复制之后更改了)并且他希望保留原样没有解释每一个细节。
希望更好的答案可以解释它。