By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,412 Members | 1,007 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,412 IT Pros & Developers. It's quick & easy.

Using transform() in a function

P: n/a
I have a question about using the STL transform algorithm in a function.

What I want to do is define a group of array classes to represent
APL-style arrays (arrays in which the number of dimensions and the
length of any dimension can be changed at any time). What I currently
plan is to have an abstract base class at the top, to allow
polymorphism, e.g.:

#include "basedefs.h" // Basic data types, e.g. typedef long Integer

typedef vector<Integer> Dimensions;

class Array {
private:
Dimensions shape;

public:
bool IsScalar() { return shape.empty(); }

...
};

and then have a child template array class so that I can have arrays of
characters, booleans, integers, doubles, and pointers (to support arrays
of arrays). The data would be stored as vector<type>, since Bjarne
Stroustrup does not recommend using valarrays for arrays intended to
vary in size after they are created, with sets of array indices resolved
into single indices into the vector as needed, possibly by implementing
a vector version of gslice and so on.

Now, I want to be able to perform a number of operations on these
arrays, following some simple rules regarding compatible dimensions.
For example, for numeric arrays, I want to be able to add two arrays to
produce a new array. For example, add(a, b) would add corresponding
elements of arrays a and b. I define a function to check if the arrays
have identical dimensions, so we know what elements to match up:

bool Conform (const Array &l, const Array &r) {
return l.shape == r.shape;
}

Then, to support a wide variety of binary operations using the same
shape rules, I would like to do something like this:

Array ScalarDyadic (const Array &l, const Array &r, BinaryFunction op) {
Array a;

if (l.IsScalar()) {
transform (r.start(), r.end(), a.start(), bind1st(op, *l.start()));
}
else if (r.IsScalar()) {
transform (l.start(), l.end(), a.start(), bind2nd(op, *r.start()));
}
else if (Conform (l, r)) {
transform (l.start(), l.end(), r.start(), a.start(), op);
}
else throw invalid_dimensions;

return a;
}

But I am not sure how to declare the third (operation) argument,
presumably a functor, so I can pass it to transform(). The STL
documentation seems to imply that there is a general functor type
called BinaryFunction, but I do not see this in the STL header files,
and I have seen no indications that the functors used have to be
derived from a standard class. On the other hand, I could probably
define the arguent as a template, but then I would end up creating a
large number of copies of the ScalarDyadic() function, one for each
operation. In that case it would probably be more efficient to pass
pointers to binary functions in order to avoid using a template, but I
don't know if transform() would support that.

I would appreciate suggestions.

Thanks.

--- Brian
Jul 22 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a

"Brian McGuinness" <br****************@lmco.com> wrote in message
news:3f**************************@posting.google.c om...
I have a question about using the STL transform algorithm in a function.
[snip]

But I am not sure how to declare the third (operation) argument,
presumably a functor, so I can pass it to transform(). The STL
documentation seems to imply that there is a general functor type
called BinaryFunction, but I do not see this in the STL header files,
and I have seen no indications that the functors used have to be
derived from a standard class.
It's called std::binary_function and its in the <functional> header file.
But it isn't for deriving from in the way that you are thinking. The purpose
of deriving from std::binary_function is to define certain typedefs such as
result_type.
On the other hand, I could probably
define the arguent as a template, but then I would end up creating a
large number of copies of the ScalarDyadic() function, one for each
operation.
I think that is what you are going to have to do.
In that case it would probably be more efficient to pass
pointers to binary functions in order to avoid using a template, but I
don't know if transform() would support that.


A pointer to a binary function is fine for std::transform, but it is likely
to be less efficient not more. Pointers to functions are potentially less
efficient than functors because they cannot be inlined.

john
Jul 22 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.