指定类的基类的C模板参数的使用和缺点?
背景
最近我一直在考虑如何设计一个特定的软件,有一点我已经制作了下面这篇文章: template <typename ... Mixins> class Foo : public virtual Mixins... { /* ... */ }; 我的想法是能够根据用户的需要使用其他属性或行为来扩充基类.假设一个应用程序需要使用带有标识号的Foos.也许其他一些应用程序需要能够用颜色来谈论Foos.可以通过添加以下类来满足这些需求: class HasID { int m_id = -1; public: int getID() { return m_id; } void assignID(int id) { m_id = id; } }; class HasColor { public: int color = 0; }; 问题 我对这段代码的两个问题如下: >使用这样的模板有什么用处和缺点? 附加示例代码 这是另一个示例,展示了可以打印扩充类对象的详细信息. 打印功能: // Default printBase template <typename Base> void printBase(std::ostream& out,Base& x) {} // printBase for HasID template <> void printBase(std::ostream& out,HasID& x) { out << ",ID=" << x.getID(); } // printBase for HasColor template <> void printBase(std::ostream& out,HasColor& x) { out << ",color=" << x.color; } // Recursive step of printBases template <typename Derived,typename Base,typename ... Bases> void printBases(std::ostream& out,Derived& x,Base& y) { printBase(out,y); printBases<Derived,Bases...>(out,x,x); } // Base case of printBases template <typename Derived> void printBases(std::ostream& out,Derived& y) {} // ostream operator template <typename ... Mixins> std::ostream& operator<<(std::ostream& out,Foo<Mixins...>& x) { out << "<Foo"; printBases<Foo<Mixins...>,Mixins...>(out,x); return out << '>'; } 主要: int main() { Foo<> plainFoo; Foo<HasID> fooWithID; fooWithID.assignID(42); Foo<HasID,HasColor> multiTalentedFoo; multiTalentedFoo.assignID(1234); multiTalentedFoo.color = 0xff0000; std::cout << plainFoo << 'n' << fooWithID << 'n' << multiTalentedFoo << 'n'; } 输出: <Foo> <Foo,ID=42> <Foo,ID=1234,color=16711680> 解决方法
CRTP“奇怪地反复出现模板模式”或有时也称为“mixin”. https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern 我们真的想再次讨论这里的缺点,而网络知道这种模式/成语吗?讨论得足够多了:-) https://softwareengineering.stackexchange.com/questions/123886/is-crtp-used-much-and-why-it-is-isnt 本文http://www.drdobbs.com/building-more-flexible-types-with-mixins/184402056注释:
这不再是真的,因为对于c 14,你有很好的机会用可变参数模板和基类的构造函数调用链来杀死那个参数.继承&委托构造者也将为此目的提供帮助. 与所有模板一样,您必须记住每个实例化都是一种新类型,可能会导致可执行文件中出现大量代码重复.我经常使用这种模式并接受成本.另一种方法是手工编写可执行大小不小的代码.你必须为你需要付出代价. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |