I have various classes in a C++0x framework and would like to write functions to convert between some of them. For example:
struct Foo { float v; };
struct Bar { int i; };
struct Tar { float p, q; };
void Convert(const Foo& x, Bar& y) { y.i = static_cast<int>(x.v); }
void Convert(const Tar& x, Foo& y) { y.v = x.p + x.q; }
This is just an example. There are quite a lot of “small” classes. And not all conversion functions make sense.
Additionally there are some classes which essentially behave like STL containers and should “inherit” these conversion functions.
void Convert(const std::vector<Foo>& cx, std::vector<Bar>& cy) { ... }
void Convert(const std::vector<Tar>& cx, std::vector<Bar>& cy) { ... }
No I am looking for an easy way to define theses functions. I tried:
template<typename X, typename Y>
void Convert(const std::vector<X>& cx, std::vector<Y>& cy) {
cy.resize(cx.size());
for(std::size_t i=0; i<cx.size(); i++) {
Convert(cx[i], cy[i]);
}
}
and this works perfectly.
However with such a setup one has to write
std::vector<X> cx = { ... };
std::vector<Y> cy;
Convert(cx, cy);
// when not specifying the type, one needs to use this form f(X, &Y)
With a setup like
template<typename X, typename Y>
std::vector<Y> Convert(const std::vector<X>& cx) {
std::vector<Y> cy(cx.size());
for(std::size_t i=0; i<cx.size(); i++) {
cy[i] = Convert(cx[i]);
}
return cy;
}
one has to write
std::vector<X> cx = { ... };
std::vector<Y> cy = Convert<X,Y>(cx);
// can I avoid specifying the source type with this form?
Of course at some point the target type need to be mentioned, but the source type is defined by the function parameter. I do not want to mention it again and again.
Is there a elegant generic way to handle such conversion functions?
Edited the question for clarification
Actually I found out how to do this. By re-ordering the template arguments
one can write
and the compiler automatically infers the second template type for input. Nice feature!