【问题标题】:C++ how to apply a function to vector elementsC ++如何将函数应用于向量元素
【发布时间】:2018-07-17 05:34:02
【问题描述】:

我想写一个 C++ 函数来对一个向量应用 (lambda) 函数并返回另一个相同大小的向量:

template <class T, class UnaryOperator>
T transform_vector(const T& input, UnaryOperator op)
{
    T output;
    std::transform(input.begin(), input.end(), std::back_inserter(output), op);
    return output;
}

如果函数op 返回类型与T 相同,则此代码有效。有没有办法告诉编译器输出向量的类型与op的返回函数相同,以使这段代码在一般情况下工作?

【问题讨论】:

  • 您能否在可行的地方添加一些代码,在不可行的地方添加一些代码,以更好地说明您需要解决的问题?

标签: c++ c++11 templates vector transform


【解决方案1】:

有没有办法告诉编译器输出向量的类型与操作的返回函数相同,以使这段代码在一般情况下工作?

-- 编辑 -- std::decay&lt;&gt; 在 Barry 的评论之后系统地添加(谢谢!)

我想像(如果你可以使用 C++14)

template <class T, class UnaryOperator>
auto transform_vector(const T& input, UnaryOperator op)
{
    std::vector<std::decay_t<decltype(op(*input.begin()))>> output;
    std::transform(input.begin(), input.end(), 
                   std::back_inserter(output), op);
    return output;
}

对于 C++11 来说有点复杂(而且是多余的),因为你不能简单地使用 auto 作为返回类型

template <class T, class UnaryOperator>
auto transform_vector(const T& input, UnaryOperator op)
   -> std::vector<typename std::decay<decltype(op(*input.begin()))>::type>
{
    std::vector<typename std::decay<decltype(op(*input.begin()))>::type>
       output;
    std::transform(input.begin(), input.end(), 
                   std::back_inserter(output), op);
    return output;
}

从 C++11 开始工作并避免冗余的另一种方法是通过具有默认值的第三个模板类型参数。

这有点复杂,但我(恕我直言)更有趣,因为允许通过 decltype() 避免自动扣除并强加不同的返回类型。

template <typename T, typename UO,
   typename RetV = std::vector<typename std::decay<decltype(std::declval<UO>()
                                        (*std::declval<T>().begin()))>::type>>
RetV transform_vector (T const & input, UO op)
{
    RetV output;
    std::transform(input.begin(), input.end(), 
                   std::back_inserter(output), op);
    return output;
}

这也适用于 C++11。

从 C++14 开始,您可以使用 std::decay_t&lt;T&gt; 而不是 typename std::decay&lt;T&gt;::type 进行简化。

【讨论】:

  • 您的解决方案通常有效(刚刚使用 C++14 进行了测试)。谢谢
  • @motam79 - 用另一种方式改进了答案(稍微复杂一点,但(恕我直言)更可取),没有冗余,应该从 C++11 开始工作。
  • 太棒了,我不知道可以在模板 中定义另一个“派生类型”。如果将空向量传递给函数,它也可以工作。
  • 您需要将std::decay_t 添加到调用op 的结果中
  • @Barry - 你是对的,很明显。但是我的大脑无法习惯std::decay。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-21
  • 2013-08-28
  • 2022-11-02
  • 1970-01-01
  • 1970-01-01
  • 2012-07-14
  • 1970-01-01
相关资源
最近更新 更多