参数类型自动演绎和匿名lambda函数

时间:2021-03-01 22:27:45

Lets say I have these lines of code;

假设我有这些代码行;

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

However, I dont want to specify the argument type in my lambda functions, ie, I want to write something like this;

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

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

Is there anyway this can be achieved?

这有可能实现吗?

(boost::lambda doesn't need types to be specified...)

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


Update:

更新:

For now I use a macro: #define _A(container) decltype(*std::begin(container)) so I can do:

现在我使用一个宏:#define _A(容器)decltype(*std::begin(容器)),这样我就可以:

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

4 个解决方案

#1


29  

No. "Polymorphic lambdas" is what this feature was referred to during the C++ committee discussions, and it was not standardized. The parameter types of a lambda must be specified.

不。“多态lambdas”是c++委员会讨论中提到的特性,它并不是标准化的。必须指定lambda的参数类型。

You can use decltype though:

你可以使用解密类型:

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

#2


11  

Your preferred syntax is legal as of C++14, and is referred to as a generic lambda or polymorphic lambda.

您首选的语法在c++ 14中是合法的,并被称为泛型lambda或多态性lambda。

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

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}));

I suppose now the question is, why can't we use this syntax for regular functions?

我想现在的问题是,为什么我们不能在常规函数中使用这种语法呢?

auto && f(auto && x) { return x; }

auto && f(auto && x) {return x;}

#3


3  

If you have a container you may try something like this

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

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

#4


0  

Try this:

试试这个:

#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;
}

You might also be able to do some funky stuff with lambdas that don't return void and also with variadic templates to pass in multiple params to the lambda.

你也可以用不会返回void的lambda来做一些有趣的事情,也可以用变量模板将多个params传递给lambda。

#1


29  

No. "Polymorphic lambdas" is what this feature was referred to during the C++ committee discussions, and it was not standardized. The parameter types of a lambda must be specified.

不。“多态lambdas”是c++委员会讨论中提到的特性,它并不是标准化的。必须指定lambda的参数类型。

You can use decltype though:

你可以使用解密类型:

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

#2


11  

Your preferred syntax is legal as of C++14, and is referred to as a generic lambda or polymorphic lambda.

您首选的语法在c++ 14中是合法的,并被称为泛型lambda或多态性lambda。

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

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}));

I suppose now the question is, why can't we use this syntax for regular functions?

我想现在的问题是,为什么我们不能在常规函数中使用这种语法呢?

auto && f(auto && x) { return x; }

auto && f(auto && x) {return x;}

#3


3  

If you have a container you may try something like this

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

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

#4


0  

Try this:

试试这个:

#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;
}

You might also be able to do some funky stuff with lambdas that don't return void and also with variadic templates to pass in multiple params to the lambda.

你也可以用不会返回void的lambda来做一些有趣的事情,也可以用变量模板将多个params传递给lambda。