【问题标题】:"Ambiguous call to overloaded function"“对重载函数的模糊调用”
【发布时间】:2014-09-19 08:12:39
【问题描述】:

我有一个这样的结构,struct Baz 继承自 2 个不同的结构,Foo 和 Bar。

我有 2 个方法调用相同的东西,一个带有 Foo 参数,一个带有 Baz 参数。

struct Foo
{
};

struct Bar
{
};

struct Baz : Foo, Bar
{
    virtual void something(const Foo& foo)
    {
    };

    virtual void something(const Bar& bar)
    {
    };
};

我这样称呼它

Baz baz;
baz.something(baz);

可以理解,如果我将 Baz 实例传递给我的代码,我知道我正在调用哪个函数,这是可以理解的。我收到“对重载函数的模糊调用”。

我知道我可以将我的 Baz 转换为 Foo 或 Bar 来解决问题...

Baz baz;
baz.something((Bar)baz);

...但是还有其他方法可以解决这个设计问题吗?

仅当传递的对象不是 Bar 类型时,我才想调用 Foo 方法。

编辑:

如果这是 C#(不是),我可能可以使用模板 where 子句来解决这个问题。

【问题讨论】:

  • 那么,在这种情况下,您究竟希望编译器做什么? (你到底为什么要这样做?)Baz 可以同时转换为FooBar。您需要以某种方式告诉编译器您想要哪个 - 我想您可以将 Baz 显式转换为在 C++11 中删除的 Foo,这意味着它不可用。或者为调用Bar 版本的Baz 实现something...
  • 为什么你必须给这些方法起相同的名字?您可以通过使用不同的名称来避免歧义。我无法理解编写这个奇怪代码的必要性。
  • 请告诉我你的意思不是horrible as this
  • 好的,我去重组一下。我不得不同意。想我只会在 Bar 中添加一个 Foo 的实例,这样它将使用 Bar 函数,除非 foo.Bar 被传递。更好?

标签: c++ inheritance overloading


【解决方案1】:

首先,请注意您使用的演员表会创建一个临时对象。你可能是这个意思:

baz.something(static_cast<Bar&>(baz));

为了回答您的问题,应该可以为此使用 SFINAE:

struct Baz : Foo, Bar
{
  virtual void something(const Bar &bar)
  { /* ... */ }

  template <
    class T,
    class = typename std::enable_if<
      std::is_convertible<const T&, const Foo&>::value &&
      !std::is_convertible<const T&, const Bar&>::value
    >::type
  >
  void something (const T &foo)
  { something_impl(static_cast<const Foo&>(foo)); }

private:
  virtual void something_impl(const Foo &foo)
  { /* ... */ }
};

Live example

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-11
    • 2011-12-12
    • 2014-09-05
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多