我想做这样的事情:
template <typename T> class Foo { ... public: void DoSomething() { compile_time_if (T is ClassA) { m_T.DoThingOne(); m_T.DoThingTwo(); } DoSomeFooPrivateThing(); m_T.DoThingThree(); } T m_T; };
在这种情况下,我知道所有有效的T实现DoThingThree,但只有ClassA实现DoThingOne和DoThingTwo.这不是一个鸭子类型的东西,我只想为ClassA做这个额外的部分,我不想将这些方法添加到其他可能的Ts.我不能做转换,因为可能的Ts不是继承类型.
我知道我可以使用外部帮助器模板来满足这个要求:
template <typename T> void Foo_DoSomething(T& t) { t.DoThingThree(); } template <> void Foo_DoSomething(ClassA& t) { t.DoThingOne(); t.DoThingTwo(); t.DoThingThree(); } template <typename T> class Foo { ... public: void DoSomething() { Foo_DoSomething(m_T); } ... };
但是现在这个外部模板无权访问Foo的私有成员(无法调用DoSomeFooPrivateThing),这限制了它的功能,并且它公开暴露给外部,这并不漂亮. (将外部方法变成朋友会让事情变得更糟.)
另一个看似合理的选择是在内部实施:
template <typename T> class Foo { ... public: void DoSomething() { DoSomethingImpl(m_T); } ... private: template <typename T2> void DoSomethingImpl(T2& t) { DoSomeFooPrivateThing(); t.DoThingThree(); } template <> void DoSomethingImpl(ClassA& t) { t.DoThingOne(); t.DoThingTwo(); DoSomeFooPrivateThing(); t.DoThingThree(); } ... };
但这需要复制外部模板类型和参数.这可能是可以接受的,但它仍然感觉有点奇怪.遗憾的是它实际上并没有编译(至少在GCC中没有编译,因为它反对类中的特化).
解决方法
我认为你的最后一个选择是最好的选择.
代替
template <> void DoSomethingImpl(ClassA& t) { t.DoThingOne(); t.DoThingTwo(); DoSomeFooPrivateThing(); t.DoThingThree(); }
你可以使用(这里不需要使用模板):
void DoSomethingImpl(ClassA& t) { t.DoThingOne(); t.DoThingTwo(); DoSomeFooPrivateThing(); t.DoThingThree(); }
原文地址:https://www.jb51.cc/c/118705.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。