双重继承类型推导

huangapple go评论202阅读模式
英文:

Double inheritance type deduction

问题

我有以下的模板类:

  1. template<class T>
  2. class Foo {
  3. public:
  4. void Bar(T* t) { member = t; }
  5. private:
  6. T* member;
  7. };

这个类被另一个类作为基类使用(两次):

  1. class AwesomeClass : public Foo<ISomeInterface>, public Foo<IOtherInterface> {};

然后像这样调用:

  1. class Caller {
  2. void Init(ISomeInterface * i) {
  3. AwesomeClass a;
  4. a.Bar(i);
  5. }
  6. }

然而,这段代码无法编译,报错说对Bar的调用是模棱两可的。因此,我需要使用a.Foo<ISomeInterface>::Bar(i),因为显然编译器无法确定要调用哪个Bar(即使给出了一个ISomeInterface对象)。有没有什么解决方法?

另外,我想知道在这里使用继承是否是“正确”的方法,或者组合是否更好一些。

英文:

I have the following template class:

  1. template&lt;class T&gt;
  2. class Foo {
  3. public:
  4. void Bar(T* t) { member = t; }
  5. private:
  6. T* member;
  7. };

This is used (twice) as a base class for a different class:

  1. class AwesomeClass : public Foo&lt;ISomeInterface&gt;, public Foo&lt;IOtherInterface&gt; {};

Which is then called something like this:

  1. class Caller {
  2. void Init(ISomeInterface * i) {
  3. AwesomeClass a;
  4. a.Bar(i);
  5. }
  6. }

However this does not compile, stating that the call to Bar is ambiguous. Therefore I need to use a.Foo&lt;ISomeInterface&gt;::Bar(i), because apparently the compiler cannot determine which Bar to call (even thought it is given an ISomeInterface object). Any ways around this?

Also I am wondering if inheritance is the 'correct' approach here or if composition would be a better option.

答案1

得分: 4

你可以将 Bar 引入 AwesomeClass 中,然后两者都可以在 AwesomeClass 的作用域中找到,然后进行重载解析。例如:

  1. class AwesomeClass : public Foo<ISomeInterface>, public Foo<IOtherInterface> {
  2. public:
  3. using Foo<ISomeInterface>::Bar;
  4. using Foo<IOtherInterface>::Bar;
  5. };

LIVE

英文:

You can introduce Bars into AwesomeClass, then both can be found in scope of AwesomeClass then overload resolution kicks in. E.g.

  1. class AwesomeClass : public Foo&lt;ISomeInterface&gt;, public Foo&lt;IOtherInterface&gt; {
  2. public:
  3. using Foo&lt;ISomeInterface&gt;::Bar;
  4. using Foo&lt;IOtherInterface&gt;::Bar;
  5. };

LIVE

答案2

得分: 1

你想要友元函数和ADL(关联依赖查找)。这样一来,你就不需要从每个基类中单独使用using来使用每个这样的方法。

  1. template <typename T>
  2. class Foo
  3. {
  4. T *member = nullptr;
  5. public:
  6. friend void Bar(Foo &self, T *t)
  7. {
  8. self.member = t;
  9. }
  10. };
  1. void Init(ISomeInterface *i)
  2. {
  3. AwesomeClass a;
  4. Bar(a, i);
  5. }
英文:

You want friend functions and ADL. This way you don't need to individually using every such method from every base.

  1. template &lt;typename T&gt;
  2. class Foo
  3. {
  4. T *member = nullptr;
  5. public:
  6. friend void Bar(Foo &amp;self, T *t)
  7. {
  8. self.member = t;
  9. }
  10. };
  1. void Init(ISomeInterface * i)
  2. {
  3. AwesomeClass a;
  4. Bar(a, i);
  5. }

huangapple
  • 本文由 发表于 2023年8月9日 14:59:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76865321.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定