如何定义依赖于参数包转换的函数的返回类型?

时间:2018-07-30 08:04:49

标签: c++ templates template-meta-programming

我正在尝试编写一个模板化函数,该函数将可变对的输入作为输入,对每个“第一个”成员和每个“第二个”成员应用某个函数,并返回结果对。我设法编写了函数本身,但无法获得自动推断的返回类型。如何使用std::result_of获得所需的结果?

我的尝试如下:

template<typename Output, typename Func, typename... Inputs>
std::pair<Output, Output> fmap(Func&& f, Inputs&&... inputs)
{
  using Out = typename std::result_of<Func(decltype(inputs.first)...)>::type;
  return std::pair<Out, Out>(f((inputs.first)...),
                             f((inputs.second)...));
  // Here I would like Out to be the same type as Output
}

int add(int i, int j)
{
  return i + j;
}

int main()
{
  std::pair<int, int> pair{1, 2};
  std::pair<int, int> pair2{4, 5};
  auto res = fmap(add, pair, pair2);
  // Crashes with template argument deduction failed, couldn't deduce Output
  std::cout << res2.first << " " << res2.second << std::endl;
  return 0;
}

2 个答案:

答案 0 :(得分:3)

我认为这就是你想要的

template<typename Func, typename... Inputs>
auto fmap(Func&& f, Inputs&&... inputs) 
-> std::pair<typename std::result_of<Func(decltype(inputs.first)...)>::type, typename std::result_of<Func(decltype(inputs.first)...)>::type>
{
  using Out = typename std::result_of<Func(decltype(inputs.first)...)>::type;
  return std::pair<Out, Out>(f((inputs.first)...),
                             f((inputs.second)...));
}

https://wandbox.org/permlink/TE6v3vgyOBumHCKV

答案 1 :(得分:2)

IMO使用make_pair可以使这一点更清洁:

template<typename Func, typename... Inputs>
auto fmap(Func&& f, Inputs&&... inputs) 
    -> std::pair<typename std::result_of<Func(decltype(inputs.first)...)>::type, 
                 typename std::result_of<Func(decltype(inputs.first)...)>::type> // not needed in C++17
{
    return std::make_pair(f((inputs.first)...), f((inputs.second)...));
}

https://wandbox.org/permlink/MbNhIfoYvHd2vZ7A
https://wandbox.org/permlink/rM6HUcWINOd60EqZ