0

for example, I have a pair array (which is a static variable) a[] which represents coordinates of points A,B,C:

pair<float,float> MyClass::a[]={{0,0},{320,568},{640,0}};

and I want another array b[] which stores the length of AB and BC:

float MyClass::b[sizeof(a)/sizeof(pair<float,float>)-1]={
    sqrt((a[1].first-a[0].first)*(a[1].first-a[0].first)+(a[1].second-a[0].second)*(a[1].second-a[0].second)),
    sqrt((a[2].first-a[1].first)*(a[2].first-a[1].first)+(a[2].second-a[1].second)*(a[2].second-a[1].second))
};

but b[] is not very maintainable because if I add elements to a[], I need to change b[] manually. Is there any methods which can generate b[] automatically? Is there anything such like e.g.: macros

float b[]={MACRO(a)};

or

float b[]={MACRO(sizeof(a)/sizeof(pair<float,float>))};

or template:

template<int i>
struct s{
    float b[]={something a[i+1]-a[i]};
};

s<sizeof(a)/sizeof(pair<float,float>)> _s;

or other design patterns that allows me to change size of a[] without changing b[] manually or even no need to modify other parts of codes?

ggrr
  • 7,737
  • 5
  • 31
  • 53

2 Answers2

1

One obvious answer would be to use a vector instead of an array:

template <class T, size_t N>
size_t elements(T (&array)[N]) {
    return N;
}

// could also use a vector for a, if desired:
pair<float,float> a[]={{0,0},{320,568},{640,0}};
vector<float> b;

for (int i=1; i<elements(a); i++) {
    float dx = a[i].first - a[i-1].first;
    float dy = a[i].second - a[i-1].second;
    b.push_back(sqrt(dx*dx + dy * dy));
}

With this, a change in the size of a doesn't require any other changes for b to track its size correctly.

There are, of course, other ways the job could be done. For example, if you were doing this quite a lot, you could wrap it all up in a class. I'm not sure that really gains anything meaningful though.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

The biggest problem here is the use of C arrays; they're not easy to initialize. With std::array, it is very easy:

pair<float,float> MyClass::a[]={{0,0},{320,568},{640,0}};
auto b = sqrt(a);

with

template<typename T, size_t N>
std::array<T, N> sqrt(std::pair<T,T> (&points)[N])
{
   using std::sqrt;
   std::array<T, N> retval;
   for (int i = 0; i != N; ++i) {
       retval[i] = sqrt(points[i].first * points[i].first + 
                        points[i].second * points[i].second) ;
   }
  return retval;

}

MSalters
  • 173,980
  • 10
  • 155
  • 350