双重继承类型推导

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

Double inheritance type deduction

问题

我有以下的模板类:

template<class T>
class Foo {
  public:
    void Bar(T* t) { member = t; }
  private:
    T* member;
};

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

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

然后像这样调用:

class Caller {
  void Init(ISomeInterface * i) {
    AwesomeClass a;
    a.Bar(i);
   }
}

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

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

英文:

I have the following template class:

template&lt;class T&gt;
class Foo {
  public:
    void Bar(T* t) { member = t; }
  private:
    T* member;
};

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

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

Which is then called something like this:

class Caller {
  void Init(ISomeInterface * i) {
    AwesomeClass a;
    a.Bar(i);
   }
}

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 的作用域中找到,然后进行重载解析。例如:

class AwesomeClass : public Foo<ISomeInterface>, public Foo<IOtherInterface> {
public:
    using Foo<ISomeInterface>::Bar;
    using Foo<IOtherInterface>::Bar;
};

LIVE

英文:

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

class AwesomeClass : public Foo&lt;ISomeInterface&gt;, public Foo&lt;IOtherInterface&gt; {
public:
    using Foo&lt;ISomeInterface&gt;::Bar;
    using Foo&lt;IOtherInterface&gt;::Bar;
};

LIVE

答案2

得分: 1

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

template <typename T>
class Foo
{
    T *member = nullptr;
    
  public:
    friend void Bar(Foo &self, T *t)
    {
        self.member = t;
    }
};
void Init(ISomeInterface *i)
{
    AwesomeClass a;
    Bar(a, i);
}
英文:

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

template &lt;typename T&gt;
class Foo
{
    T *member = nullptr;
    
  public:
    friend void Bar(Foo &amp;self, T *t)
    {
        self.member = t;
    }
};
void Init(ISomeInterface * i)
{
    AwesomeClass a;
    Bar(a, i);
}

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:

确定