среда, 16 января 2013 г., 3:20:45 UTC+4 пользователь Sylvester Hesp написал:
Let consider a simple example. Assume that we need to write an unary predicate in the frames of the C++2003 Standard. It could look the following way
class UnaryPredicate : public std::unary_function<int, bool>
{
public:
UnaryPredicate( const int a[] ) : a( a ) {}
bool operator ()( int x ) { return ( x == *a++ ); }
protected:
const int *a;
};
Now if we would rewtite it as a lambda expression it would be natural to suppose that the equivalent lambda expression will look the following way
[a]( int x ) mutable { return ( x == *a++ ); }
where a is some one-dimensional integer array.
Here [a] corresponds to UnaryPredicate( const int a[] ) : a( a ) {}
and return ( x == *a++ ); corresponds to bool operator ()( int x ) { return ( x == *a++ ); }
I will repeat that this supposing is natural.
However this code will not be compiled in the frames of the C++ 2011 Standard. Instead of implicitly converting the array to a pointer the compiler will copy the whole array. Do I need this?! I I would like to deal with the whole array I would write [&a] and use sizeof( a ) if it is very needed.
Ville says that here arrays captured by copy the same way as it would be done when one cstructure is assigned to other structure. But here there is no any assignments of structures or using a default copy constructor. Here an array itself is used and arrays has no such operation as the assignment.
I do not know where it can be required for standard algorithms to copy the whole array in a functional object. At least till now I did not see such code. I think that such functional object will be ineffective. If you indeed need to copy a whole array and make it a local object then you can write a separate function. Lambda expressions should not be overloaded with such resourse consuming operations.
Returning to the example I showed that to get the same rresult I need to introduce an intermediate variable. This makes the code less obvious becuse the link between the array and lambda will be lost. For example
int a[N] = { /* some values */ };
int *p = a;
auto lm = [p]( int x ) mutable { return ( x == *p++ ); };
So every time some intermediate variable has to be used. It hides the linkage between the lambda and the array.
So I cannot get equivalent code for a C++ 2003 functional object without some tricks.