在c++ 11中,是否有一种方法来模板lambda函数?还是它本身就太具体了,无法被模板化?

我知道我可以定义一个经典的模板化类/函子,但问题更像是:语言是否允许模板化lambda函数?


当前回答

我知道这个问题是关于c++ 11的。然而,对于那些在谷歌上搜索并登陆这个页面的人来说,c++ 14现在支持模板化lambdas,并被称为泛型lambdas。

现在大多数流行的编译器都支持这个特性。微软Visual Studio 2015支持。叮当声的支持。GCC支持。

其他回答

我一直在使用最新的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;
}

我想知道这是怎么回事:

template <class something>
inline std::function<void()> templateLamda() {
  return [](){ std::cout << something.memberfunc() };
}

我使用类似的代码,生成一个模板,不知道编译器是否会优化“包装”函数。

这里有一个解决方案,涉及到将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++ 11中,lambda函数不能被模板化,但是在下一个版本的ISO c++标准(通常称为c++ 14)中,将引入这个特性。(来源)

使用的例子:

auto get_container_size = [] (auto container) { return container.size(); };

注意,尽管语法使用了关键字auto,但类型推导不会使用auto类型推导的规则,而是使用模板参数推导的规则。另请参阅通用lambda表达式的建议(以及对此的更新)。

看看Boost。用于多态lambdas的Phoenix: http://www.boost.org/doc/libs/1_44_0/libs/spirit/phoenix/doc/html/index.html 顺便说一下,不需要c++ 0x:)