W.F. W.F. - 1 month ago 6
C++ Question

Why generic lambdas are allowed while nested structs with templated methods aren't?

As far as I understand - generic lambdas are transformed into objects of local scope structs with templated

operator()
. This makes generic lambda very powerful and easy to use tool. On the other hand one can create structs nested into the function, when however the struct has templated member e.g.:

#include <iostream>

int main() {
struct inner {
template <class T>
void operator()(T &&i) { }
};
return 0;
}


or is templated by itself:

int main() {
template <class T>
struct inner {
void operator()(T &&i) { }
};
return 0;
}


compiler seems to have a problem with compiling it:


error: invalid declaration of member template in local class


and

error: a template declaration cannot appear at block scope



I assume the problem lays more in c++ standard than in compiler bug. What are the reasons lambdas are allowed to have templated members and not the local structures?

I found this qustion, but I think the answer is kind of outdated (I don't think it's true even for c++11).

Answer

This is core issue 728, which was filed before generic lambdas were a thing. There is no technical reason for local classes not being able to have member templates (which is clearly proven by generic lambdas); the constraint was introduced sometime between January and May 1994, with no paper covering it, but we can get an idea of the prevailing notions from this paper's justification of why local classes shall not be template arguments:

Class templates and the classes generated from the template are global scope entities and cannot refer to local scope entities.

Local classes can be template arguments now, but no one saw enough incentive to bring member templates of local classes into discussion; not even when the language needed to implicitly generate them for a new feature.