在c++ 11中,是否有一种方法来模板lambda函数?还是它本身就太具体了,无法被模板化?
我知道我可以定义一个经典的模板化类/函子,但问题更像是:语言是否允许模板化lambda函数?
在c++ 11中,是否有一种方法来模板lambda函数?还是它本身就太具体了,无法被模板化?
我知道我可以定义一个经典的模板化类/函子,但问题更像是:语言是否允许模板化lambda函数?
当前回答
有一个允许lambda模板的gcc扩展:
// create the widgets and set the label
base::for_each(_widgets, [] <typename Key_T, typename Widget_T>
(boost::fusion::pair<Key_T, Widget_T*>& pair) -> void {
pair.second = new Widget_T();
pair.second->set_label_str(Key_T::label);
}
);
where _widgets是一个std::tuple< fusion::pair<Key_T, Widget_T>…>
其他回答
我一直在使用最新的clang版本5.0.1,使用-std=c++17标记进行编译,现在对lambdas的自动类型参数提供了一些很好的支持:
#include <iostream>
#include <vector>
#include <stdexcept>
int main() {
auto slice = [](auto input, int beg, int end) {
using T = decltype(input);
const auto size = input.size();
if (beg > size || end > size || beg < 0 || end < 0) {
throw std::out_of_range("beg/end must be between [0, input.size())");
}
if (beg > end) {
throw std::invalid_argument("beg must be less than end");
}
return T(input.begin() + beg, input.begin() + end);
};
auto v = std::vector<int> { 1,2,3,4,5 };
for (auto e : slice(v, 1, 4)) {
std::cout << e << " ";
}
std::cout << std::endl;
}
这里有一个解决方案,涉及到将lamba包裹在一个结构中:
template <typename T>
struct LamT
{
static void Go()
{
auto lam = []()
{
T var;
std::cout << "lam, type = " << typeid(var).name() << std::endl;
};
lam();
}
};
使用do:
LamT<int>::Go();
LamT<char>::Go();
#This prints
lam, type = i
lam, type = c
这样做的主要问题是(除了额外的类型之外)你不能将这个结构定义嵌入到另一个方法中,否则你会得到(gcc 4.9)
error: a template declaration cannot appear at block scope
我也试过这样做:
template <typename T> using LamdaT = decltype(
[](void)
{
std::cout << "LambT type = " << typeid(T).name() << std::endl;
});
我希望我可以这样使用它:
LamdaT<int>();
LamdaT<char>();
但是我得到了编译器错误:
error: lambda-expression in unevaluated context
所以这行不通……但是即使它编译了,它的作用也是有限的 使用,因为我们仍然必须把“使用LamdaT”在文件范围 (因为它是一个模板)这在某种程度上违背了lambdas的目的。
在c++ 20中,可以使用以下语法:
auto lambda = []<typename T>(T t){
// do something
};
c++ 11的另一个解决方法是定义一个模板函数并将其包装在lambda表达式中。然而;这需要为不同的模板化lambdas定义一个新函数:
struct ST{ int x; };
template<class T>
T templateFunc(T variable)
{
return variable;
}
void func()
{
ST st{10};
auto lambda = [&](){return templateFunc<ST>(st);};
auto res = lambda();
}
我知道这个问题是关于c++ 11的。然而,对于那些在谷歌上搜索并登陆这个页面的人来说,c++ 14现在支持模板化lambdas,并被称为泛型lambdas。
现在大多数流行的编译器都支持这个特性。微软Visual Studio 2015支持。叮当声的支持。GCC支持。