69
struct Test
{
  static const int value = []() -> int { return 0; } ();
};

With gcc-4.6 I get something like, error: function needs to be constexpr. I have tried multiple combinations of putting constexpr at various places, but no luck.

Is constexpr supported for lambda functions as well (irrespective of return type specified or not) ? What is the correct syntax ?

Any work around possible ?

iammilind
  • 68,093
  • 33
  • 169
  • 336
  • Under what circumstances would a `constexpr` lambda function be useful? It seems to me like it would only end up adding another pair of braces around the actual expression – bdonlan Jun 21 '11 at 03:51
  • @bdonlan, I have a use case for that (to calculate number of `__VA_ARGS__` in macro). But explaining that will be a whole new question. – iammilind Jun 21 '11 at 03:54
  • 2
    Also see [Why are lambda expressions not allowed in an unevaluated operands but allowed in the unevaluated portions of constant expressions?](http://stackoverflow.com/q/22232164/1708801) – Shafik Yaghmour Sep 21 '15 at 14:04

4 Answers4

41

Update: As of C++17, lambdas are permitted in constant expressions.


Lambdas are currently (C++14) not allowed in constant expressions as per [expr.const]/(2.6), but they will once N4487 is accepted (which can be found in the working draft N4582):

This proposal suggests allowing lambda-expressions in constant expressions, removing an existing restriction. The authors propose that certain lambda-expressions and operations on certain closure objects be allowed to appear within constant expressions. In doing so, we also propose that a closure type be considered a literal type if the type of each of its data-members is a literal type; and, that if the constexpr specifier is omitted within the lambda-declarator, that the generated function call operator be constexpr if it would satisfy the requirements of a constexpr function (similar to the constexpr inference that already occurs for implicitly defined constructors and the assignment operator functions).

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • I suppose making lambdas `constexpr` is a necessary step towards making STL algorithms `constexpr` as well since STL algorithms frequently take lambdas as arguments. Many (all?) of them were indeed made `constexpr` in C++20. – adentinger Jun 16 '22 at 14:14
  • 1
    @AnthonyD973 constexpr-ification of the library is indeed a major overhaul and will likely be extended to the vast majority thereof. – Columbo Jul 20 '22 at 21:53
29

From the C++0x FDIS §7.1.5[dcl.constexpr]/1:

The constexpr specifier shall be applied only to the definition of a variable, the declaration of a function or function template, or the declaration of a static data member of a literal type.

A lambda expression is none of those things and thus may not be declared constexpr.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • Workaround for what? What are you trying to accomplish with a `constexpr` lambda expression? Why can you not use an ordinary function or function template? – James McNellis Jun 21 '11 at 03:57
  • I am able to calculate number of `__VA_ARGS__` of macro at run time using lambda expression. Just making it `constexpr` will be a compile time constant. Explaining that will be a detailed new topic. I know that there are `boost` alternatives available, but the method I have used seems to me very straight forward and handy. – iammilind Jun 21 '11 at 03:59
  • 2
    Why not just use a `VA_NARGS` and do the computation at preprocessing (see the example [at the beginning of this answer](http://stackoverflow.com/questions/6194031/iterating-variadic-macro-arguments/6194669#6194669)). – James McNellis Jun 21 '11 at 04:03
  • 1
    Or how about using variadic templates and `sizeof...()`? Something like `template Counter { static const size_t N = sizeof...(Args); };`, and then use `Counter::N`, if your macro arguments are types... or something more elaborate with `constexpr size_t f(Args... args) const { return sizeof...(Args); }` if your arguments aren't types. – Kerrek SB Jun 21 '11 at 12:28
  • In general since preprocessor macros expand where they're used and can't go back and declare functions somewhere earlier, lambdas give them a lot of added power. If lambdas worked with constexpr, then that power could be applied to template arguments. I don't know to what end, but it seems potentially very powerful. And now it's a new annoying C++ inconsistency to remember. Lambda functions can do what regular functions can oh except constexpr :P – Joseph Garvin Aug 13 '11 at 21:45
  • Is this still true in C++14? – Joseph Garvin Jul 28 '15 at 16:37
  • 1
    @JosephGarvin yes. Variable templates were added to the things that can be `constexpr` but nothing regarding lambdas. – Marco A. Aug 22 '15 at 13:17
  • Thanks for the answer. As we are moving closer towards C++17, I am accepting another (year old) post for the future visitors. I notice that another good answer posted today which suggests relevance of lambda & `constexpr` relation. – iammilind Aug 09 '16 at 10:43
19

Prior to C++17 lambdas are not compatible with constexpr. They cannot be used inside constant expressions.

Starting with C++17 lambdas are constexpr where it makes sense. The proposal N4487 will be put into the C++17 standard. On his website Herb Sutter, chair of the ISO C++ committee, stated the following:

Lambdas are now allowed inside constexpr functions.

Ralph Tandetzky
  • 22,780
  • 11
  • 73
  • 120
10

FFWD to year 2018 :)

auto my_const_expression_lambda = []()
  constexpr -> bool
{
   return true ;
}

Since c++17