Can lambda functions be templated?

前端 未结 11 2478
你的背包
你的背包 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 02:02

    C++11 lambdas can't be templated as stated in other answers but decltype() seems to help when using a lambda within a templated class or function.

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    template<typename T>
    void boring_template_fn(T t){
        auto identity = [](decltype(t) t){ return t;};
        std::cout << identity(t) << std::endl;
    }
    
    int main(int argc, char *argv[]) {
        std::string s("My string");
        boring_template_fn(s);
        boring_template_fn(1024);
        boring_template_fn(true);
    }
    

    Prints:

    My string
    1024
    1
    

    I've found this technique is helps when working with templated code but realize it still means lambdas themselves can't be templated.

    0 讨论(0)
  • 2020-11-28 02:02

    I'm not sure why nobody else has suggested this, but you can write a templated function that returns lambda functions. The following solved my problem, the reason I came to this page:

    template <typename DATUM>
    std::function<double(DATUM)> makeUnweighted() {
      return [](DATUM datum){return 1.0;};
    }
    

    Now whenever I want a function that takes a given type of argument (e.g. std::string), I just say

    auto f = makeUnweighted<std::string>()
    

    and now f("any string") returns 1.0.

    That's an example of what I mean by "templated lambda function." (This particular case is used to automatically provide an inert weighting function when somebody doesn't want to weight their data, whatever their data might be.)

    0 讨论(0)
  • 2020-11-28 02:05

    I wonder what about this:

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

    I used similar code like this, to generate a template and wonder if the compiler will optimize the "wrapping" function out.

    0 讨论(0)
  • 2020-11-28 02:07

    UPDATE 2018: C++20 will come with templated and conceptualized lambdas. The feature has already been integrated into the standard draft.


    UPDATE 2014: C++14 has been released this year and now provides Polymorphic lambdas with the same syntax as in this example. Some major compilers already implement it.


    At it stands (in C++11), sadly no. Polymorphic lambdas would be excellent in terms of flexibility and power.

    The original reason they ended up being monomorphic was because of concepts. Concepts made this code situation difficult:

    template <Constraint T>
    void foo(T x)
    {
        auto bar = [](auto x){}; // imaginary syntax
    }
    

    In a constrained template you can only call other constrained templates. (Otherwise the constraints couldn't be checked.) Can foo invoke bar(x)? What constraints does the lambda have (the parameter for it is just a template, after all)?

    Concepts weren't ready to tackle this sort of thing; it'd require more stuff like late_check (where the concept wasn't checked until invoked) and stuff. Simpler was just to drop it all and stick to monomorphic lambdas.

    However, with the removal of concepts from C++0x, polymorphic lambdas become a simple proposition again. However, I can't find any proposals for it. :(

    0 讨论(0)
  • 2020-11-28 02:09

    In C++11, lambda functions can not be templated, but in the next version of the ISO C++ Standard (often called C++14), this feature will be introduced. [Source]

    Usage example:

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

    Note that though the syntax uses the keyword auto, the type deduction will not use the rules of auto type deduction, but instead use the rules of template argument deduction. Also see the proposal for generic lambda expressions(and the update to this).

    0 讨论(0)
提交回复
热议问题