双重继承类型推断

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

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-2.html
匿名

发表评论

匿名网友

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

确定