Lambda expressions as class template parameters

前端 未结 5 1576
星月不相逢
星月不相逢 2020-11-29 20:05

Can lambda expressions be used as class template parameters? (Note this is a very different question than this one, which asks if a lambda expression itself can be

5条回答
  •  感情败类
    2020-11-29 20:38

    As of C++20, this answer is now outdated. C++20 introduces stateless lambdas in unevaluated contexts1:

    This restriction was originally designed to prevent lambdas from appearing in signatures, which would have opened a can of worm for mangling because lambdas are required to have unique types. However, the restriction is much stronger than it needs to be, and it is indeed possible to achieve the same effect without it

    Some restrictions are still in place (e.g. lambdas still can't appear on function signatures), but the described usecase is now completely valid and the declaration of a variable is no longer necessary.


    I'm asking if you can do something like:

    Foovoid { })> foo;
    

    No you can't, because lambda expressions shall not appear in an unevaluated context (such as decltype and sizeof, amongst others). C++0x FDIS, 5.1.2 [expr.prim.lambda] p2

    The evaluation of a lambda-expression results in a prvalue temporary (12.2). This temporary is called the closure object. A lambda-expression shall not appear in an unevaluated operand (Clause 5). [ Note: A closure object behaves like a function object (20.8).—end note ] (emphasis mine)

    You would need to first create a specific lambda and then use decltype on that:

    auto my_comp = [](const std::string& left, const std::string& right) -> bool {
      // whatever
    }
    
    typedef std::unordered_map<
      std::string,
      std::string,
      std::hash,
      decltype(my_comp)
      > map_type;
    

    That is because each lambda-derived closure object could have a completely different type, they're like anonymous functions after all.

提交回复
热议问题