【问题标题】:C++: Template and LambdaC++:模板和 Lambda
【发布时间】:2018-12-17 00:57:27
【问题描述】:

在 C++ 中使用类似以下的内容是否常见?

template <typename T> function<void(vector<T> &)> filter1 = [ ] (vector<T> &vec){
    int count = 0;
    for (T t : vec){
        if ( t.cost < 500 )
            vec.erase(vec.begin()+count);
        count++;
    }
};

template <typename T> void discount(float p, vector<T> &vec){
    filter1<T>(vec);
    int count = 0;
    for (T t : vec) {
        t.cost = t.cost - t.cost * p;
        vec.erase(vec.begin() + count);
        vec.emplace(vec.begin() + count, t);
        count++;
    }

顺便说一句,我称它为 tembda,因为它是模板和 Lambda 的混合体。

【问题讨论】:

  • 无论如何你都可以remove_if (stackoverflow.com/questions/36384571/…) 为什么只使用向量?你可以比这更笼统
  • 顺便说一句,你的 lambda 调用了 UB。
  • vec.erase(vec.begin() + count); vec.emplace(vec.begin() + count, t); 你的意思是for(T&amp; t : vec) 并去掉那些行。
  • 不,这只是可怕的 c++,而且它是错误的(基于范围的擦除是 ub。您需要使用基于迭代器的迭代并将擦除的返回值分配给迭代器)。跨度>
  • 成语的出现是因为它们有一个很好的潜在原因。你这样做的原因是什么?

标签: c++


【解决方案1】:

在 C++ 中使用类似以下的内容是否常见?

没有。

首先,std::function 是一种重量级抽象,在这种情况下会不必要地降低代码的性能。其次,与简单的模板函数相比,在这里使用 lambda 表达式没有任何优势——你只会让阅读你代码的人感到困惑。

【讨论】:

  • 拥有一个通用 lambda 可能是一个优势 - 与模板函数的特定特化相比,这些更容易传递给通用算法。
【解决方案2】:

Template lambdas will be a part of C++20, but your intent was common enough to include in C++14.

C++14 通过auto 而不是&lt;typename T&gt; 支持这一点:

auto filter_out_low_prices = [] (auto& vec) {
    auto predicate = [](const auto& t){ return t.cost < 500.00; };
    vec.erase(std::remove_if(std::begin(vec), std::end(vec), predicate),
            std::end(vec));
};

template <class V>
void discount(const float p, V& vec){
    filter_out_low_prices(vec);
    for (auto& t : vec)
        t.cost = t.cost - t.cost * p;
}

这避免了使用 std::function 来实现轻量级,正如 Vittorio Romeo 所建议的那样。它还使用remove_if 来避免未定义的行为,并且不限于std::vector,正如doctorlove 建议的那样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    • 1970-01-01
    相关资源
    最近更新 更多