【问题标题】:Argument type auto deduction and anonymous lambda functions参数类型自动推导和匿名 lambda 函数
【发布时间】:2011-04-19 07:10:41
【问题描述】:

假设我有这些代码行;

std::vector<int> ints;
std::for_each(ints.begin(), ints.end(), [](int& val){ val = 7; });

但是,我不想在我的 lambda 函数中指定参数类型,即我想写这样的东西;

std::for_each(ints.begin(), ints.end(), [](auto& val){ val = 7; });

有没有办法做到这一点?

(boost::lambda 不需要指定类型...)


更新:

现在我使用宏:#define _A(container) decltype(*std::begin(container)),所以我可以这样做:

std::for_each(ints.begin(), ints.end(), [](_A(ints)& val){ val = 7; });

【问题讨论】:

  • 至少为此,为什么不只是std::fill(ints.begin(), ints.end(), 7);
  • 是的,在这种情况下可以使用 std::fill,但是,这不是我的问题。
  • 这就是为什么我输入它作为评论,而不是答案......

标签: c++ lambda c++11


【解决方案1】:

没有。 “多态 lambdas”是 C++ 委员会讨论期间提到的这个特性,它没有标准化。必须指定 lambda 的参数类型。

您可以使用decltype

std::for_each(ints.begin(), ints.end(), [](decltype(*ints.begin())& val){ val = 7; });

【讨论】:

  • 该死,我已经尽可能频繁地使用 auto 开发了一个相当不错的流程。
  • typedef decltype(*beg(ints)) 类型;如果您认为 decltype 语法很费力。
  • 多态/泛型 lambdas 是 C++14 的一部分:en.wikipedia.org/wiki/C%2B%2B14#Generic_lambdas
【解决方案2】:

您的首选语法自 C++14 起是合法的,称为泛型 lambda 或多态 lambda。

http://isocpp.org/blog/2013/04/n3649-generic-polymorphic-lambda-expressions-r3

auto lambda = [](auto x) { return x; };
lambda(5);
lambda("hello");
lambda(std::vector<int>({5, 4, 3}));

从 C++20 开始,我们也可以将这种语法用于常规函数:

auto f(auto x) { return x; }

【讨论】:

    【解决方案3】:

    如果你有一个容器,你可以试试这样的东西

    template<typename Container>
    void reset(Container c)
    {
       for_each(c.begin(),c.end(),[](typename Container::reference val) { val=7; });
    }
    

    【讨论】:

    • 如果您的函数不是模板函数而是适用于具体类型(如我的情况),您可以简单地执行以下操作:std::for_each(ints.begin(), ints.end(), [](ints::reference val) { ... });
    【解决方案4】:

    试试这个:

    #include <functional>
    #include <algorithm>
    #include <iostream>
    
    template <typename ValTy>
    std::function<void(ValTy&)> polymorphicLambda ()
    {
        return std::function<void(ValTy&)> ([](ValTy& val) -> void { val = 7; } );
    }
    
    int main()
    {
        std::vector<int> ints(5);
    
        std::generate_n(ints.begin(), 5, []() { return 0; });
        std::for_each(ints.begin(), ints.end(), [](int& val) { std::cout << val << "\t"; });
        std::cout << std::endl;
    
        std::for_each(ints.begin(), ints.end(), polymorphicLambda<int>());
        std::for_each(ints.begin(), ints.end(), [](int& val) { std::cout << val << "\t"; });
        std::cout << std::endl;
    
    
        std::vector<double> doubles(5);
    
        std::generate_n(doubles.begin(), 5, []() { return 0; });
        std::for_each(doubles.begin(), doubles.end(), [](double& val) { std::cout << val << "\t"; });
        std::cout << std::endl;
    
        std::for_each(doubles.begin(), doubles.end(), polymorphicLambda<double>());
        std::for_each(doubles.begin(), doubles.end(), [](double& val) { std::cout.precision(2); std::cout << std::fixed << val << "\t"; });
        std::cout << std::endl;
    
        return 0;
    }
    

    您还可以使用不返回 void 的 lambda 以及可变参数模板来做一些时髦的事情,以将多个参数传递给 lambda。

    【讨论】:

    • 我不明白?什么是胜利?
    • 胜利是不必为每个参数类型重新声明你的 lambda。但它并没有解决您的问题
    • 我也不清楚为什么要使用它而不是标准模板函数声明
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    • 2016-01-11
    相关资源
    最近更新 更多