Dra*_*rax 37 c++ lambda variadic c++14
从C++ 14开始,我们可以使用泛型lambdas:
auto generic_lambda = [] (auto param) {};
Run Code Online (Sandbox Code Playgroud)
这基本上意味着它的调用操作符基于标记为auto的参数进行模板化.
问题是如何创建一个可以接受可变参数数量的lambda,类似于可变参数函数模板的工作方式?如果这不可能,最接近的东西可以用同样的方法吗?你会怎么存储它?有可能std::function
吗?
mka*_*aes 41
我不确定你的意图是什么,但不是将它存储在一个std::function
你可以使用lambda本身来捕获params.这是在boost邮件列表中讨论的示例.它用于boost :: hana实现
auto list = [](auto ...xs) {
return [=](auto access) { return access(xs...); };
};
auto head = [](auto xs) {
return xs([](auto first, auto ...rest) { return first; });
};
auto tail = [](auto xs) {
return xs([](auto first, auto ...rest) { return list(rest...); });
};
auto length = [](auto xs) {
return xs([](auto ...z) { return sizeof...(z); });
};
// etc...
// then use it like
auto three = length(list(1, '2', "3"));
Run Code Online (Sandbox Code Playgroud)
Dra*_*rax 30
你如何创建一个可变的通用lambda?
您可以使用以下语法创建可变参数通用lambda:
auto variadic_generic_lambda = [] (auto... param) {};
Run Code Online (Sandbox Code Playgroud)
基本上你只需要添加...
之间auto
(可能REF合格)和你的参数包名称.
所以通常使用通用引用会给出:
auto variadic_generic_lambda = [] (auto&&... param) {};
Run Code Online (Sandbox Code Playgroud)
你如何使用这些参数?
您应该将variadic泛型参数视为具有模板参数包类型,因为它就是这种情况.这或多或少意味着大多数(如果不是全部)这些参数的使用将需要模式以这种方式或另一种方式.
这是一个典型的例子:
#include <iostream>
void print(void)
{
}
template <typename First, typename ...Rest>
void print(const First& first, Rest&&... Args)
{
std::cout << first << std::endl;
print(Args...);
}
int main(void)
{
auto variadic_generic_lambda = [] (auto... param)
{
print(param...);
};
variadic_generic_lambda(42, "lol", 4.3);
}
Run Code Online (Sandbox Code Playgroud)
你如何存储一个可变的通用lambda?
您可以使用auto
将lambda存储在自己类型的变量中,也可以将其存储在a中,std::function
但只能使用您为其指定的固定签名来调用它std::function
:
auto variadic_generic_lambda = [] (auto... param) {};
std::function<void(int, int)> func = variadic_generic_lambda;
func(42, 42); // Compiles
func("lol"); // Doesn't compile
Run Code Online (Sandbox Code Playgroud)
可变系列通用lambda的集合怎么样?
由于每个lambda具有不同的类型,因此您无法将其直接类型存储在STL的通常的同类容器中.使用非泛型lambdas的方法是将它们存储在一个对应的中std::function
,它将具有固定的签名调用,并且不会限制任何内容,因为你的lambda首先不是通用的,只能以这种方式调用:
auto non_generic_lambda_1 = [] (int, char) {};
auto non_generic_lambda_2 = [] (int, char) {};
std::vector<std::function<void(int, char)>> vec;
vec.push_back(non_generic_lambda_1);
vec.push_back(non_generic_lambda_2);
Run Code Online (Sandbox Code Playgroud)
如本存储部分的第一部分所述,如果您可以限制自己使用给定的固定调用签名,那么您可以对可变参数通用lambda执行相同的操作.
如果你不能,你将需要某种形式的异类容器,如:
std::vector<boost::variant>
std::vector<boost::any>
boost::fusion::vector
请参阅此问题以获取异质容器的示例.
有关lambdas的更多常规信息以及有关生成的成员以及如何在lambda中使用参数的详细信息,请参阅:
小智 6
考虑这个
#include <iostream>
namespace {
auto out_ = [] ( const auto & val_)
{
std::cout << val_;
return out_ ;
};
auto print = [](auto first_param, auto... params)
{
out_(first_param);
// if there are more params
if constexpr (sizeof...(params) > 0) {
// recurse
print(params...);
}
return print;
};
}
int main()
{
print("Hello ")("from ")("GCC ")(__VERSION__)(" !");
}
Run Code Online (Sandbox Code Playgroud)
并且看不到模板。(就在下面:) )没有看起来像无线电噪音的 C++ 代码。简单,干净,最重要的是:
难怪“感觉就像一门新语言”。
归档时间: |
|
查看次数: |
17615 次 |
最近记录: |