【问题标题】:Can't use the lambda function inside function template不能在函数模板中使用 lambda 函数
【发布时间】:2018-11-06 07:50:29
【问题描述】:

我的函数模板有问题。

我有 3 个不同的集合,并且我有集合的迭代器。现在我必须创建一个函数模板 'apply' 它将执行以下操作: 1.遍历集合的所有元素,检查谓词是否为真:

1.1 如果谓词返回 true - 则需要使用 lambda 'passed'

更改集合元素

1.2 if predicate return false = then 集合元素需要用 lambda 改变 'rejected'

请给我一个例子,我应该怎么写。

非常感谢您的帮助。此处更新代码:

#include <iostream>
#include <vector>
#include <list>
#include <functional>

using namespace std;

template<typename T>
void apply(T collBegin, T collEnd, function<bool(int)> f1, function<int(int)> f2, function<int(int)> f3)
{
    for (T actualPosition = collBegin; actualPosition != collEnd; ++actualPosition) {
        if (f1(*actualPosition)) {
            //the argument matches the predicate function f1
            *actualPosition = f2(*actualPosition);
        }
        else {
            //the argument doesn't match the predicate function f1
            *actualPosition = f3(*actualPosition);
        }
    }
}

int main()
{
    int arr[]{ 1,2,3,4,5,6,7,8,9 };

    auto predicate = [](int arg) -> bool { return arg % 2 == 0; };

    auto passed = [](int arg) -> int { return arg / 2; };

    auto rejected = [](int arg) -> int { return (3 * arg) + 1; };

    apply(arr, arr + std::size(arr), predicate, passed, rejected);

    std::vector<int> vec(arr, arr + std::size(arr));
    apply(vec.begin(), vec.end(), predicate, passed, rejected);

    std::list<int> lis(vec.begin(), vec.end());
    apply(lis.begin(), lis.end(), predicate, passed, rejected);


    for (auto e : lis) std::cout << e << " ";
    std::cout << '\n';
}

此代码有效。但我想将它从 int 更改为 T。我该怎么做?

【问题讨论】:

  • stackoverflow.com 上的所有问题都必须以纯文本形式包含问题本身中的所有相关信息。指向外部网站的可疑链接,可能随时停止工作,使问题变得毫无意义,是不可接受的。
  • 我更正了这个。很抱歉。
  • 您的一个 lambda 与其他的不同。然而,您声明它们的 std::function 类型是相同的。有你的问题。此外,向量迭代器不是普通指针,因此尝试将它们用作 T * 也不会起作用。
  • Sooo 代码应该是什么样子的?你能写一个例子吗?
  • 小心:有一个std::apply。它可能还没有发生,但你最终可能会不小心调用它,或者至少当它出现在错误消息中时会感到困惑。这就是为什么你不应该写 using namespace std; 它将适用于一切。

标签: c++ c++11 templates lambda std-function


【解决方案1】:

Sooo 代码应该是什么样子的?你能写一个例子吗?

以下编译并运行,但我不确定这是否是您想要的:

#include <iostream>
#include <vector>
#include <list>
#include <functional>
#include <algorithm>

template<typename T, typename U>
void apply(T collBegin, T collEnd, std::function<bool(U const &)> f1, std::function<U(U const &)> f2, std::function<U(U const &)> f3)
{
    std::for_each(collBegin, collEnd, [&](auto &el) { el = f1(el) ? f2(el) : f3(el); });
}

int main()
{
    std::function<bool(int const &)> predicate = [](int const &arg) -> bool { return arg % 2 == 0; };
    std::function<int(int const &)> passed = [](int const &arg) -> int { return arg / 2; };
    std::function<int(int const &)> rejected = [](int const &arg) -> int { return (3 * arg) + 1; };

    int arr[]{ 1,2,3,4,5,6,7,8,9 };
    apply(arr, arr + sizeof(arr)/sizeof(int), predicate, passed, rejected);

    std::vector<int> vec(arr, arr + sizeof(arr) / sizeof(int));
    apply(vec.begin(), vec.end(), predicate, passed, rejected);

    std::list<int> lis(vec.begin(), vec.end());
    apply(lis.begin(), lis.end(), predicate, passed, rejected);

    for (auto e : lis) std::cout << e << " ";
    std::cout << '\n';
}

https://ideone.com/A30Dl9

1 2 16 4 4 5 34 1 7 

【讨论】:

  • 谢谢,我已经更新了代码,看起来很棒。但我有一个问题:如何从这里将 int 更改为 T 类型以使我的函数和整个程序像模板函数一样适用?
  • @Tomas2929 我对模板做了一点改动,在传递 lambda 时必须明确,将其设为 std::function,以便可以推断出参数类型。
  • 谢谢 - 我已经测试过了,它可以工作。但我有最后一个问题:对于通过的类型有什么要求,所以 lambda 确实有效?请解释一下好吗?
  • @Tomas2929 添加了逻辑,但说真的,如果你不能向你的老师解释它是如何工作的,你现在就有麻烦了;)
  • 非常感谢您的帮助。我们可以关闭话题了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 2020-07-19
  • 2010-12-13
  • 2014-05-17
相关资源
最近更新 更多