From the wikipedia article about Lambda functions and expressions:
users will often wish to define predicate functions near the place where they make the algorithm function call. The language has only one mechanism for this: the ability to define a class inside of a function. ... classes defined in functions do not permit them to be used in templates
Does this mean that use of nested structure inside function is silently deprecated after C++0x lambda are in place ?
Additionally, what is the meaning of last line in above paragraph ? I know that nested classes cannot be template
; but that line doesn't mean that.
I'm not sure I understand your confusion, but I'll just state all the facts and let you sort it out. :)
In C++03, this was legal:
#include <iostream>
int main()
{
struct func
{
void operator()(int x) const
{
std::cout << x << std::endl;
}
};
func f; // okay
f(-1); // okay
for (std::size_t i = 0; i < 10; ++i)
f(i) ; // okay
}
But if we tried doing this, it wasn't:
template <typename Func>
void exec(Func f)
{
f(1337);
}
int main()
{
// ...
exec(func); // not okay, local classes not usable as template argument
}
That left us with an issue: we want to define predicates to use for this function, but we can't put it in the function. So we had to move it to whatever outer scope there was and use it there. Not only did that clutters that scope with stuff nobody else needed to know about, but it moved the predicate away from where it's used, making it tougher to read the code.
It could still be useful, for the occasional reused chunk of code within the function (for example, in the loop above; you could have the function predicate to some complex thing with its argument), but most of the time we wanted to use them in templates.
C++0x changes the rules to allow the above code to work. They additionally added lambdas: syntax for creating function objects as expressions, like so:
int main()
{
// same function as above, more succinct
auto func = [](int x){ std::cout << x << std::endl; };
// ...
}
This is exactly like above, but simpler. So do we still have any use for "real" local classes? Sure. Lambda's fall short of full functionality, after all:
#include <iostream>
template <typename Func>
void exec(Func func)
{
func(1337);
}
int main()
{
struct func
{
// note: not possible in C++0x lambdas
void operator()(const char* str) const
{
std::cout << str << std::endl;
}
void operator()(int val) const
{
std::cout << val << std::endl;
}
};
func f; // okay
f("a string, ints next"); // okay
for (std::size_t i = 0; i < 10; ++i)
f(i) ; // okay
exec(f); // okay
}
That said, with lambda's you probably won't see local classes any more than before, but for completely different reasons: one is nearly useless, the other is nearly superseded.
Is there any use case for class inside function after introduction of lambda ?
Definitely. Having a class inside a function is about:
Obviously there's a threshold where having a large class inside a function harms readability and obfuscates the flow of the function itself - for most developers and situations, that threshold is very low. With a large class, even though only one function is intended to use it, it may be cleaner to put both into a separate source file. But, it's all just tuning to taste.
You can think of this as the inverse of having private functions in a class: in that situation, the outer API is the class's public interface, with the function kept private. In this situation, the function is using a class as a private implementation detail, and the latter is also kept private. C++ is a multi-paradigm language, and appropriately gives such flexibility in modelling the hierarchy of program organisation and API exposure.
Examples:
float
or double
for access to the mantisa/exponent/sign, and decides internally to model the value using a struct
with suitable-width bitfields for convenience (note: implementation defined behaviours)classes defined in functions do not permit them to be used in templates
I think you commented that someone else's answer had explained this, but anyway...
void f()
{
struct X { };
std::vector<X> xs; // NOPE, X is local
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With