Can lambda functions be templated?

前端 未结 11 2477
你的背包
你的背包 2020-11-28 01:44

In C++11, is there a way to template a lambda function? Or is it inherently too specific to be templated?

I understand that I can define a classic templated class/fu

相关标签:
11条回答
  • 2020-11-28 01:47

    I've been playing with the latest clang version 5.0.1 compiling with the -std=c++17 flag and there is now some nice support for auto type parameters for 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;
    }
    
    0 讨论(0)
  • 2020-11-28 01:49

    Have a look at Boost.Phoenix for polymorphic lambdas: http://www.boost.org/doc/libs/1_44_0/libs/spirit/phoenix/doc/html/index.html Does not require C++0x, by the way :)

    0 讨论(0)
  • 2020-11-28 01:49

    There is a gcc extension which allows lambda templates:

    // 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 is a std::tuple< fusion::pair<Key_T, Widget_T>... >

    0 讨论(0)
  • 2020-11-28 01:49

    Here is one solution that involves wrapping the lamba in a structure:

    template <typename T>                                                   
    struct LamT                                                             
    {                                                                       
       static void Go()                                                     
       {                                                                    
          auto lam = []()                                                   
          {                                                                 
             T var;                                                         
             std::cout << "lam, type = " << typeid(var).name() << std::endl;
          };                                                                
    
          lam();                                                            
       }                                                                    
    };   
    

    To use do:

    LamT<int>::Go();  
    LamT<char>::Go(); 
    #This prints 
    lam, type = i
    lam, type = c
    

    The main issue with this (besides the extra typing) you cannot embed this structure definition inside another method or you get (gcc 4.9)

    error: a template declaration cannot appear at block scope
    

    I also tried doing this:

    template <typename T> using LamdaT = decltype(                          
       [](void)                                                          
       {                                                                 
           std::cout << "LambT type = " << typeid(T).name() << std::endl;  
       });
    

    With the hope that I could use it like this:

    LamdaT<int>();      
    LamdaT<char>();
    

    But I get the compiler error:

    error: lambda-expression in unevaluated context
    

    So this doesn't work ... but even if it did compile it would be of limited use because we would still have to put the "using LamdaT" at file scope (because it is a template) which sort of defeats the purpose of lambdas.

    0 讨论(0)
  • 2020-11-28 01:52

    I am aware that this question is about C++11. However, for those who googled and landed on this page, templated lambdas are now supported in C++14 and go by the name Generic Lambdas.

    [info] Most of the popular compilers support this feature now. Microsoft Visual Studio 2015 supports. Clang supports. GCC supports.

    0 讨论(0)
  • 2020-11-28 01:52

    In C++20 this is possible using the following syntax:

    auto lambda = []<typename T>(T t){
        // do something
    };
    
    0 讨论(0)
提交回复
热议问题