超类operator()错误 - 含糊不清

时间:2014-10-24 19:40:09

标签: c++ overloading ambiguous

我正在尝试使用C ++ 11来定义一个类,它可以存储多个std::function<>并根据它们的参数类型调用它们,类似于重载决策。

我为每个函数签名声明了一个基类,并且#9;重载&#39;功能应该支持:

template <typename R, typename... A>
struct overload;

template <typename R, typename... A>
struct overload<R(A...)>
{
  typedef std::function<R(A...)> F;
  F f_;
  overload(F f): f_(f) {}
  R operator()(A... a)
  {
    return f_(a...);
  }
};

template <typename... T>
struct overloaded_function : public overload<T>...
{
  overloaded_function(T... t): overload<T>(t)... {}
};

int main()
{
  overloaded_function<void(float), void(int, int)> f([](float){}, [](int, int){});
  f(1.F);  // build error
  f(2, 3); // build error
  return 0;
}

构建错误:(Visual Studio 2013)

  

&#34; overload :: operator()[with R = void,A =]&#34;很暧昧   c:\ Users \ benj7280 \ Documents \ kernel_builder \ src \ main.cpp 39 5 kernel_builder

我不明白操作符是如何模糊的,因为函数具有完全不同的签名。当我完全删除模板时,只使用具体的类,以及当我用命名的成员函数替换operator()重载时,错误完全相同。

1 个答案:

答案 0 :(得分:1)

您需要将基类operator()包含在using中。但是,我不知道如何使用参数包来做到这一点,所以希望其他人可以参与并回答这个问题。

我可以做的是重做你的结构,使它一直线性地继承,每次重载只需要using下一个:

template <typename... T>
struct overloads
{
    // need this one so that the last overload has 
    // something to "using". If you have an overload for void(),
    // that one will hide this one. If you don't, and call f(),
    // this won't compile... which is fine.
    void operator()();
};

template <typename R, typename... A, typename... T>
struct overloads<R(A...), T...>
: overloads<T...>
{
  typedef std::function<R(A...)> F;
  F f_;

  template <typename... Fs>
  overloads(F f, Fs... fs)
  : overloads<T...>(fs...)
  , f_(f)
  {}

  using overloads<T...>::operator();

  R operator()(A... a)
  {
    return f_(a...);
  }
};

template <typename... T>
struct overloaded_function : public overloads<T...>
{
  overloaded_function(T... t)
  : overloads<T...>(t...)
  { }
};

现在你的f(1.F)f(2, 3)调用都编译,因为现在所有的重载都是......可重载的。