Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a generic lambda have no arguments?

Tags:

c++

lambda

c++14

First of all, I know I could use templated class/functor, but that is not what I want.

Here is the lambda:

auto lambda = [] (auto var) {
    decltype(var) x;

    //do stuff with x but nothing with var
};

The problem is I receive the warning C4100(unreferenced formal parameter). I also know I could use tricks such as disabling the warning and enabling it again after the lambda or using macros such as UNREFERENCED_PARAMETER, but that is cheating.

Is there any way I could accomplish that?

An ideal code would look like this:

template <typename T>
auto lambda = [] () {
    T x;

    //do stuff with x
};
like image 794
Nighteen Avatar asked Jul 02 '15 18:07

Nighteen


2 Answers

In fact, in C++14 you can create "template lambdas" using exactly the syntax you want, but only in namespace scope:

// (1)
template <typename T>
auto l = [] () {
    T x;
};

int main() {
    l<int>();
}

It's not a generic lambda, it's a variable template, but you can even create generic template lambda:

template <typename T>
auto l = [] (auto y) {
    T x = 42;
    std::cout << x + y << std::endl;
};

Demo

But there is a downside: it seems that among current compilers only Clang supports this.

Update: Since this can only be done in namespace scope, if your lambda has no arguments, or doesn't have auto arguments (that is, it's not generic), it can be replaced by a function without requiring even any C++11 features, not mentioning C++14. If such lambda has captures, they can capture only global variables, so the corresponding function may just use the same variables or their copies. Thanks to @JasonR for pointing this out:

// effectively the same as (1)
template <typename T>
void l() {
    T x;
}
like image 158
Anton Savin Avatar answered Oct 06 '22 00:10

Anton Savin


If you really don't need the argument, just wrap it in void:

auto lambda = [](auto var) {
    (void)var; // now we used it - more or less
    decltype(var) x;
    /* whatever else */
};
like image 44
Barry Avatar answered Oct 05 '22 23:10

Barry