Gilad
Gilad

Reputation: 6585

template vector to vector convert function

I have a base class that has 4 different vectors of parameters: HW,SW,FW, High level

each class derives from the base class, and needs to be able to convert from one vector of parameters to another.

Ex: convert(Vector vec1, Vector vec2);

One way of implementing is to use 16 static conversion cases. However, while there are 4 different types of vectors at the moment, more may be added at a later time.

not all the classes implements all of the 16 conversions. a lot of them will use a default conversion (which I want to implement in the base class returning "no conversion defined error");

class A: public baseClass

Class B: public baseClass

Class C: public baseClass

C::Convert(Vector<HW> vec1, Vector<SW> vec2)
{
   vec2[0] = vec1[0] +vec1[1] *1.5;
}
B::Convert(Vector<HW> vec1, Vector<SW> vec2)
{
   vec2[0] = vec1[0] +vec1[1] *3.7;
}
A::Convert(Vector<SW> vec1, Vector<HW> vec2)
{
   vec2[0] = vec1[2] +vec1[1] *9;
}

What would be a good way of defining a generic conversion? I thought maybe a template of vectors.

Template<Vector<K>, Vector<T>>
void Convert(const k& vec1, T vec2)

I can't assume that a conversion from each vector to the other exists.

Upvotes: 0

Views: 419

Answers (2)

user2288008
user2288008

Reputation:

You can use template methods, see example:

#include <iostream>
#include <vector>

class Hw {};
class Sw {};

// base class with default converters
class Base {
 public:
  template <class From, class To>
  void convert(const From& from, To& to);
};

// specialize template with default converters
template <>
void Base::convert(const std::vector<Hw>& from, std::vector<Sw>& to) {
  std::cout << "default converter" << std::endl;
}

// specialize forbidden version with runtime error
// (simply don't specialize anything to get link error, which is better)
template <>
void Base::convert(const std::vector<Hw>& from, std::vector<Hw>& to) {
  std::cout << "error converter" << std::endl;
}

// override some default behaviour
class A : public Base {
 public:
  // show you want to use other default converters
  using Base::convert;

  // special (not default) behaviour
  void convert(const std::vector<Hw>& from, std::vector<Sw>& to) {
    std::cout << "special A converter" << std::endl;
  }
};

// converter with defaults
class B : public Base {
};

int main() {
  std::vector<Hw> hw_vector;
  std::vector<Sw> sw_vector;

  A a;
  a.convert(hw_vector, sw_vector); // special A converter
  a.convert(hw_vector, hw_vector); // error converter

  B b;
  b.convert(hw_vector, sw_vector); // default converter
  b.convert(hw_vector, hw_vector); // error converter
  return 0;
}

Upvotes: 1

Israel Unterman
Israel Unterman

Reputation: 13510

Decide upon a vector that will be a base to all of them, say, Base, that each one of them can convert automatically to Base. Then all there is to do is to supply conversion from Base to all others.

So for each vector you add you need to supply 2 functions: Change automatically from it to Base, and change from Base to it.

So in order to convert from Vec1 to Vec2 you simply need a function (it's only a sketch for the templates):

Vec2 Convert<Vec1, Vec2>(Vec1 v1, Vec2 v2) {
    return v1.toBase().toVec2();
}

Upvotes: 1

Related Questions