Home > front end >  Cannot initialize a lambda member variable with a default argument
Cannot initialize a lambda member variable with a default argument

Time:12-01

I would like to compile the code below with c 17, so that I can pass any function (lambda) that has a specific signature, int(int), while also allowing the default argument:

template <class F = int(int)> // for deduction
struct A{
        A(F f = [] (int x){return x;}) : f_{f} {}

        F f_;
};

int main() {
        A work([](int x){return x   1;});
        A not_work; // compile error.
}

However, clang emits an error:

a.cpp:6:4: error: data member instantiated with function type 'int (int)'
        F f_;
          ^
a.cpp:11:4: note: in instantiation of template class 'A<int (int)>' requested here
        A not_work;
          ^

I don't understand why the member f_ can be initialized when I pass the lambda and the default lambda argument cannot be?

Meanwhile, is there any better way to do this?

CodePudding user response:

As the error message said, you can't declare a data member with a function type like int(int).

When passing a lambda to the constructor, the template parameter F would be deduced as the lambda closure type by CTAD (since C 17); when passing nothing F will use the default argument int(int) and the data member f_'s type would be int(int) too, which causes the error.

You might use a function pointer type (lambdas without capture could convert to function pointer implicitly) or std::function<int(int)>. E.g.

template <class F = int(*)(int)> // for deduction
struct A{
        A(F f = [] (int x){return x;}) : f_{f} {}

        F f_;
};

Or

template <class F = std::function<int(int)>> // for deduction
struct A{
        A(F f = [] (int x){return x;}) : f_{f} {}

        F f_;
};
  • Related