1

I have a data structure in my C++ program that has some attributes of type 'Vector' (defined by me), and some of type 'double'. In another place in my code, I would very much like to be able to iterate through this data structure, and perform the same arithmetic operations on each value. The operators that I will need are defined for Vector, so the code literally looks the same for what I would need to do for a Vector type and a double type.

If at all possible, I would like to avoid iterating through the 'Vector values' and then separately iterating through the 'double values'.

I realize this is straining the strict-typing of C++, but is there any good way to accomplish this?

EDIT:

Right now, I'm doing some routine operations like this:

e.values.vel = k0[i].vel + k1[i].vel * c_1;
e.values.acc = k0[i].acc + k1[i].acc * c_1;
....

(e and k0[i] are the same class type)

Right now, the only thing keeping me from generalizing e's type is the fact that some of e's values may be vectors, and some may be doubles, and ideally this code will deal with different objects of this type which may have different numbers or kinds of values. What I want would look like:

for (int j = 0; j < e.values.size(); j ++)
{
    e.values[j] = k0[i].values[j] + k1[i].values[j]
}

Ideally, I would have e be iterable, or provide some sort of next function, but to do that, either: it would have to store it's variables in an array which can only contain one known type, or it would provide the next function which can only return one known type.

I'm trying to find a way where I can abstract this concept so that I can iterate through something of e's type without knowing the type of each value.

cemulate
  • 2,305
  • 1
  • 34
  • 48
  • That's a bit vague. Give us something more concrete. We have a built-in compile time language so it may be possible depending on what you want to do. – Martin York Jan 23 '12 at 20:55
  • How would you "iterate through the `double` values"? Are they stored in some kind of data structure? Indeed, please be more specific, perhaps by providing relevant parts of your class definition. – nplatis Jan 23 '12 at 21:48

3 Answers3

1

Does your vector type admit multiple dimensionalities? If so, you could use 1-D Vectors as a wrapper for the intrinsic type double, and then just iterate over vectors.

class Vector {
public:
   Vector(int dimensions = 1);
   ...
   double& operator[](int index);
};

Alternatively, you could write a Vector abstract class, then implement only the dimensionalities you want: 1-, 2-, 3-d vectors are common.

class Vector {
public:
   ...
   Vector operator+(const Vector& rhs) const = 0;
   ...
};

class Vector1D : Vector {
public:
   ...
   vector operator+(const Vector& rhs) const;
}

class Vector2D : Vector {
public:
   ...
   vector operator+(const Vector& rhs) const;
}

class Vector3D : Vector {
public:
   ...
   vector operator+(const Vector& rhs) const;
}

Of course, you can do both, if you have special optimizations or functionality that applies to vectors of specific dimensionalities.

I suppose what I'm really saying is that you should just interpret doubles as 1-dimensional vectors.

Patrick87
  • 27,682
  • 3
  • 38
  • 73
  • This is an option I'll consider, but I was hoping to avoid the class overhead of a Vector whenever I didn't absolutely need it. I might end up doing this though. – cemulate Jan 23 '12 at 21:10
1

You might want to consider Boost.Fusion. It allows you to turn your type into a compile-time sequence, where you can then use a compile-time-expanding foreach to call an appropriate functor for each element.

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
  • Found this question that looks like my situation: http://stackoverflow.com/questions/1198260/iterate-over-tuple, definitely a good possibility; thanks. – cemulate Jan 23 '12 at 21:27
0

A vector uses contiguous memory much like an array, so assuming your doubles are in an array, you can iterate over both the same way. You can use a function template to treat them generically as so:

template <typename T>
void DoOperationOnSequence(size_t maxIndex, const T& container) {
    for (int i = 0; i < maxIndex; ++i) {
        //Do something with container[i];
    }
}

This should work fine, assuming your doubles are in a contiguous (one after another un-interupted in memory) sequence.

PS: sorry if this isn't what you were looking for, your questions a little hard to understand though so I just thought I'd take a stab at it :)

John Humphreys
  • 37,047
  • 37
  • 155
  • 255