I work in robotics, which means I use a large number of open-source projects dealing with 3D geometry. Since the classes and math tend to be fairly simple, everyone seems to implement their own version of Vector3D, Quaternion, etc., each with slight variations, e.g. vec.x, vec.X, vec.x(). So within one project, one might need to convert between Eigen, ROS, Assimp, Bullet, and other versions of the same basic classes. Is there an easy or elegant way to do this in C++ that doesn't require an n^2 mapping from every library to every other library?
Similar to: This SO question, but I can't edit any of the source libraries.
Example:
namespace a
{
class Vector
{
public:
double x, y, z;
};
} // namespace a
namespace b
{
class Vector
{
public:
double X, Y, Z;
};
} // namespace b
namespace c
{
class Vector
{
public:
double& x() { return mx; }
double& y() { return my; }
double& z() { return mz; }
private:
double mx, my, mz;
};
} // namespace c
int main()
{
a::Vector va;
b::Vector vb;
c::Vector vc = va + vb; // Ideal, but probably unrealistic goal
return 0;
}
EDIT:
If there are ~10 different geometry libraries, a particular project may only use 2-4 of them, so I'd like to avoid introducing a dependency on all the unused libraries. I was hoping for something like static_cast<b::Vec>(a::Vec), or maybe
c::Vec vc = my_cvt<c::Vec>(vb + my_cvt<b::Vec>(va));
but my understanding of templates and type_traits is pretty weak.
If you write three helper functions for each vector type to access X, Y and Z:
double X(const a::Vector& v) { return v.x; }
double Y(const a::Vector& v) { return v.y; }
double Z(const a::Vector& v) { return v.z; }
double X(const c::Vector& v) { return v.x(); }
double Y(const c::Vector& v) { return v.y(); }
//...
then you can easily write template functions that work with any type. e.g:
template<typename V1, typename V2>
V1 operator+(const V1& v1, const V2& v2) {
return {X(v1)+X(v2), Y(v1)+Y(v2), Z(v1)+Z(v2)};
}
template<typename V1, typename V2>
V1 convert(const V2& v) {
return {X(v), Y(v), Z(v)};
}
int main() {
a::Vector va;
b::Vector vb;
auto vc = convert<c::Vector>(va + vb);
}
Live demo.
Well, just define a operator+ function and your 'unrealistic goals' would be achieved:
c::Vector operator+(const a::Vector& a, const b::Vector& b) {
return {a.x+b.X, a.y+b.Y, a.z+b.Z};
}
And your small code snippet will work.
EDIT
If you do not want to define a hell lot of function, and assuming you can't change the Vector version from a and b, modifiy your vector class by adding these constructors:
Vector(a::Vector a) : mx(a.x), my(a.y), mz(a.z) {}
Vector(b::Vector b) : mx(b.X), my(b.Y), mz(b.Z) {}
And then define only one operator dealing only with the c class:
c::Vector operator+(c::Vector a, c::Vector b) {
return {a.x()+b.x(), a.y()+b.y(), a.z()+b.z()};
}
And your code snippet will work with declaring thousands of operator
EDIT 2
If you want your type to be compatible with your library's types you may add conversion operator to your struct, example, if you want your type to be convertible with Vector a, add this function inside your class:
operator a::Vector() const {
// return a a::Vector from our c::Vector
return a::Vector{mx, my, mz};
}
I see that this is an old question but check out Boost QVM.
Related
Suppose the "standard" C++ inheritance paradigm:
struct GeneralFunc
{
/*..members..*/
virtual double value(double a, double b) { return 0; }
};
struct Func_classA : GeneralFunc
{
/*..members..*/
double value(double a, double b) { return a * b; }
};
struct Func_classB : GeneralFunc
{
/*..members..*/
double value(double a, double b) { return a + b; }
};
void main(){
double a = 1.0, b = 1.0;
std::vector<GeneralFunc*> my_functions;
//fill my_functions from input
for (auto& f : my_functions)
{
double v = f->value(a, b);
}
}
I would like an implementation that is most efficient for the iteration, i.e. minimizes indirect references, maximizes inline optimizations, ect. To constrain the problem, I know beforehand each specific "type" I want to implement (I can define only the "func" types I require, without having to allow other possibilities).
several options appear available:
boost::polycollection
#include <boost/poly_collection/base_collection.hpp>
//...rest the same
boost::base_collection<GeneralFunc> my_functions
//...rest the same
std::variant
#include <variant>
//...rts
using funcs = std::variant<Func_classA, Func_classB /*..possibly more../*>
std::vector<funcs> my_functions
or CRTP (Curiously Recurring Template Pattern)
Let me know the correct nomenclature for this, but here I "upcast" the base class based on the "type" -- a kind of manual dispatch.
template<typename T>
struct GeneralFunc
{
/*..members..*/
int my_type;
double value(double a, double b) {
switch (my_type){
case TYPE_A:
return static_cast<Func_classA*>(this)->value(a,b);
/*..you get the idea..*/
I'm okay sacrificing marginal efficiency for ease of development, but is there a consensus on the "best practice" in this case?
EDITS* fixed some typos; my current development is "in-development" of CRTP the last option.
SOLUTION:
After testing, both boost::polycollection and std::variant are valid approaches. However, this turned out to be far most efficient (from memory, may be slightly off).
enum ftype { A = 0, B, C };
struct GeneralFunc
{
ftype my_type;
GeneralFunc(ftype t) : my_type(t) {}
inline double value(double a, double b) const; // delay definition until derived classes are defined
}
struct Func_classA : GeneralFunc
{
Func_classA() : GeneralFunc(ftype::A) {}
inline double value(double a, double b) const { return a * b; }
}
/* define B, C (& whatever) */
inline double GeneralFunc::value(double a, double b)
{
switch(my_type){
case (ftype::A):
return static_cast<Func_classA*>(this)->value(a,b);
/* same pattern for B, C, ect */
}
}
void main(){
std::vector<std::unique_ptr<GeneralFunc>> funcs;
funcs.push_back(std::make_unique<Func_classA>());
funcs.push_back(std::make_unique<Func_classB>());
funcs[0]->value(1.0,1.0); // calls Func_classA.value
funcs[1]->value(1.0,1.0); // calls Func_classB.value
}
I'd be tempted to just use std::function as the container, rather than re-writing it.
using GeneralFunc = std::function<double(double, double);
struct Func_classA
{
/*..members..*/
double value(double a, double b) { return a * b; }
/*explicit*/ operator GeneralFunc () const { return [this](double a, double b){ value(a, b) }; }
};
struct Func_classB
{
/*..members..*/
double value(double a, double b) { return a + b; }
/*explicit*/ operator GeneralFunc () const { return [this](double a, double b){ value(a, b) }; }
};
void main(){
double a = 1.0, b = 1.0;
std::vector<GeneralFunc> my_functions;
//fill my_functions from input
for (auto& f : my_functions)
{
double v = f(a, b);
}
}
I think there's an option you didn't include (which is the one I'd use for performance critical code), that is to create a tuple of function objects and "iterate" over such tuple. Unfortunately there is no nice API to iterate over a tuple, so one has to implement his own. See the snippet below
#include <tuple>
#include <functional>
template<int ... Id, typename Functions>
auto apply(std::integer_sequence<int, Id ...>, Functions& my_functions, double& v, double a, double b){
([](auto a, auto b){a=b;}(v, std::get<Id>(my_functions)( a, b )), ...);
}
int main(){
auto fA = [](double a, double b){return a*b;};
auto fB = [](double a, double b){return a+b;};
//create the tuple
auto my_functions=std::make_tuple(fA, fB);
double v=0;
double a = 1.;
double b = 1.;
//iterate over the tuple
apply(std::make_integer_sequence<int, 2>(), my_functions, v, a, b);
}
This way you create a type safe zero overhead abstraction, since the compiler knows everything about the types you use (you don't need any type erasure mechanism). Also there's no need of virtual functions (same as in CRTP), so the compiler will probably inline the function calls. The snippet above uses C++17 generic lambdas, could be also implemented in C++14 or C++11 compliant way, but it would be more verbose. I would prefer this over CRTP because to me it looks more readable: no static cast to the derived class, and no artificial hierarchy of inheritance.
EDIT: from your answer looks like you don't really need the CRTP here, what you write using the CRTP solution is equivalent to this
enum ftype { A = 0, B, C };
auto fA = [](double a, double b){return a*b;};
auto fB = [](double a, double b){return a+b;};
int main(){
std::vector<ftype> types(2);
types[0]=A;
types[1]=B;
auto value = [&types](double a, double b, ftype i){
switch(i){
case (ftype::A):
return fA(a,b);
break;
case (ftype::B):
return fB(a,b);
break;
}
};
double v=value(1., 1., A);
v=value(1., 1., B);
}
Might be a matter of taste, but I think the version above is more readable (you don't really need a common base class, or static cast to the derived class).
I have some C structs that I would like to 'extend' in C++ to add some convenience and type safety. For instance, suppose that my struct is
struct vector2D { float x, y; };
From a number of sources, I have gathered that the safest way to warp this struct in C++ is to subclass it:
struct Vector2D: vector2D { ... };
So far so good. However, what I am having difficulties figuring out how I can reinterpret the C struct as the extended version. Suppose I have a C function
struct vector2D do_some_stuff(struct vector2D _a, struct vector2D _b) {
...
}
Within this function, I would like to work with the C++ representation. Since the layouts of struct vector2D and Vector2D are identical, I though that simple cast would work, e.g.
Vector2D a = static_cast<Vector2D>(_a)
but this doesn't seem to work. Using a constructor generates horrible boilerplate code.
What is the proper way of doing this, if its at all possible?
Clarification: do_some_stuff is a C function and is only intended to be called from C code.
Prefer composition over inheritance. That is change your C++ class Vector2D to contain an instance of C struct vector2D and interface it:
class Vector2D {
vector2D p;
public:
vector2D& getP() { return p; }
vector2D const& getP() const { return p; }
float& x() { return p.x; }
float& y() { return p.y; }
float const& x() const { return p.x; }
float const& y() const { return p.y; }
// ...
};
And then call the C function as:
Vector2D v1;
Vector2D v2;
...
auto p = do_some_stuff(v1.getP(), v2.getP());
However, what I am having difficulties figuring out how I can reinterpret the C struct as the extended version.
Um, that's not how inheritance works: your daughter class is a specialization of your mother class, so you can interpret a Vector2D as a vector2d, but not the other way around.
Think about it: where should the extension's data come from if it wasn't there in the first place?
What you can do is implement a constructor or cast operator that takes a vector2d to initialize a new Vector2D.
Other than that, I'd say your whole endeavour is questionable, because it's based on a misunderstanding: The struct you're extending is a C++ class now, different from the C type.
After some experimentation, I have figured the way to do it:
Vector2D v = *reinterpret_cast<Vector2D*>(&_v);
But juanchopanza's suggestion to use non-member functions is probably the better way to go.
I'm not an advanced programmer. How can I overload the [] operator for a class that has two (or more) array/vector type variables?
class X
{
protected:
std::vector<double> m_x, m_y;
public:
double& operator[](const short &i) { return ???; }
};
What should I use for ???, or how can I do it (maybe adding other definitions?) to be able to call either variable?
Additional question: will this allow other classes of type class derived : public X access m_x and m_y for writing?
UPDATE:
Thank you everyone who answered, but I'm afraid that if I draw the line then the answer to my first question is no, and to the second yes. The longer version implies either an extra struct, or class, or plain setters/getters, which I wanted to avoid by using a simple function for all.
As it stands, the current solution is a (temporary) reference to each variable, in each class to avoid the extra X:: typing (and keep code clear), since m_x would have existed, one way or another.
you can write just a function for this, like:
double &get(unsigned int whichVector, unsigned int index)
{
return (whichVector == 0 ? m_x[index] : m_y[index]);
}
or use operator():
struct A
{
std::vector<int> a1;
std::vector<int> a2;
int operator()(int vec, int index)
{
return (vec == 0 ? a1[index] : a2[index]);
}
};
A a;
auto var = a(0, 1);
but still, this is kinda strange :) probably you should just give a const ref outside, like:
const std::vector<double> &getX() const { return m_x; }
and second question: protected will be convert into private in public inheritance (child/derived will have access to these memebers)
Assuming you want m_x and m_y indexed against the same parameter and a single return value:
struct XGetter
{
double& x;
double& y;
};
XGetter operator[](const short &i) { return { m_x[i], m_y[i] }; }
And the const overload:
struct XGetterReadOnly
{
double x;
double y;
};
XGetterReadOnly operator[](const short &i) const { return { m_x[i], m_y[i] }; }
The compiler will make a good job of optimizing away the intermediate classes XGetter and XGetterReadOnly where appropriate which maybe hard to get your head round if you're a new to C++.
If using mixin doesn't make you uncomfortable you could use tag dispatching like:
#include <utility>
#include <vector>
#include <iostream>
template <size_t I>
struct IndexedVector {
std::vector<double> v;
IndexedVector():v(10){}
};
template <size_t I>
struct tag {
int i;
};
template <size_t S, class = std::make_index_sequence<S>>
struct MixinVector;
template <size_t S, size_t... Is>
struct MixinVector<S, std::index_sequence<Is...>>: IndexedVector<Is>... {
template <size_t I>
double &operator[](tag<I> i) {
return IndexedVector<I>::v[i.i];
}
};
int main() {
MixinVector<2> mv;
mv[tag<0>{0}] = 1.0;
std::cout << mv[tag<0>{0}] << std::endl;
}
To use std::index_sequence you need however compiler supporting c++14 (you could though implement it yourself in c++11). The approach is easily expandable to any number of vectors by simple MixinVector template parameter modification.
There are many broken things, either at conceptual and design level.
Are you able to point your finger simultaneously against two distinct things? No? That's why you cannot use one index to address two distinct vector retaining their distinction.
You can do many things: whatever way to "combine" two value int one is good
by a syntactic point of view:
return m_x[i]+m_y[x] or return sin(m_x[i])*cos(m_y[i]) or return whatever_complicated_expression_you_like_much
But what's the meaning of that? The point is WHY THERE ARE TWO VECTOR IN YOUR CLASS? What do you want them to represent? What do you mean (semantically) indexing them both?
Something I can do to keep their distinction is
auto operator[](int i) const
{ return std::make_pair(m_x[i],m_y[i]); }
so that you get a std::pair<double,double> whose fist and second members are m_x[i] and m_y[i] respectively.
Or ... you can return std::vector<double>{m_x[i],m_y[i]};
About your other question: Yes, inheriting as public makes the new class able to access the protected parts: that's what protected is for.
And yes, you cam R/W: public,protected and private are about visibility, not readability and writeability. That's what const is about.
But again: what does your class represent? without such information we cannot establish what make sense and what not.
Ok, stated your comment:
you need two different funcntions: one for read (double operator[](unsigned) const) and one for write (double& operator[](unsigned) const)
If you know vectors have a known length -say 200-, that you can code an idex transforamtion like i/1000 to identify the vector and i%1000 to get the index,so that 0..199 addres the first, 1000..1199 address the second 2000..2199 address the third... etc.
Or ... you can use an std::pair<unsigned,unsigend> as the index (like operator[](const std::pair<unsigned,unsigned>& i), using i.first to identify the vector, and i.second to index into it, and then call x[{1,10}], x[{3,30}] etc.
Or ... you can chain vetor together as
if(i<m_x.size()) return m_x[i]; i-=m_x:size();
if(i<m_y.size()) return m_y[i]; i-=m_y:size();
if(i<m_z.size()) return m_z[i]; i-=m_z:size();
...
so that you index them contiguously.
But you can get more algorithmic solution using an array of vectors instead of distinct vector variables
if you have std::array<std::vector<double>,N> m; instead of m_x, m_y and m_z the above code can be...
for(auto& v: m)
{
if(i<v.size()) return v[i];
i-=v.size();
}
You can return a struct has two double
struct A{
double& x;
double& y;
A(A& r) : x(r.x), y(r.y){}
A(double& x, double& y) : x(x), y(y){}
};
class X
{
protected:
std::vector<double> m_x, m_y;
public:
A operator[](const short &i) {
A result(m_x[i], m_y[i]);
return result;
}
};
Thank for editing to #marcinj
I want to sort points_vec vector as shown in the pseudocode below. I want to sort this vector, by a coordinate value like x or y or z
class A{
std:vector<double*> points_vec;
void doSomething();
}
Then, in method A::doSomething, I want sort this vector:
void A::doSomething() {
std::sort(points_vec.begin(), points_vec.end(), sortPoints());
}
Can someone please show me syntax for the sortPoints() method.. Preferably I want it to be a method of class A. this post creates a struct to do this, not sure if I should create a similar struct within the class. Is there another way to handle this?
thanks
The simplest way is to provide a functor which is used by the sort algorithm to compare two values. You can write like this:
struct Compare
{
bool operator()(double* first, double* second) const
{
//Compare points here
}
};
And use like:
std::sort(p.begin(), p.end(), Compare());
EDIT for comment by OP: Yes, this sample code compiles fine:
class A
{
public:
struct c
{
bool operator()(int a, int b) const
{
return a < b;
}
};
};
int main()
{
std::vector<int> a1;
a1.push_back(2);
a1.push_back(1);
std::sort(a1.begin(), a1.end(), A::c());
return 0;
}
You have two options for sorting: either pass a function/functor to sort or define the operator< for your class. Now, your class A seems to be more of a wrapper for a set of coordinates. So, create another class for your co-ordinates.
struct Point {
double x_, y_, z_;
Point(double x, double y, double z) : x_(x), y_(y), z_(z) {}
// just an example, you can refine the following as much as you need
bool operator<(Point const& other) {
return x < other.x;
}
};
bool sortOnY(Point const& l, Point const& r) const {
return l.y < r.y;
}
class A {
std::vector<Point> pts_;
void doSomething() {
sort(pts_.begin(), pts_.end());
}
// if sorting on y is also required, you will need
// to use a custom comparator which can be either
// a functor or a function
void doSomeOtherThing() {
sort(pts_.begin(), pts_.end(), sortOnY);
}
};
First of all - what you have will break all your points - as you'll sort by single doubles not by "points consisting of 3 doubles".
The best way to do this I think is:
Store the points as some Point3D class not a couple doubles
Define the less then operator for Point3D
Just call std::sort(points_vec.begin(), points_vec.end() );
If you'd want to sort them by in different ways that's when you'd use the sort functor and create different functors with operators() for different purposes.
I don't think this thread would be complete without a mention of Boost.Bind:
struct Point3D {
double x, y;
Point3D(double x=0., double y=0.) : x(x), y(y) {
}
};
int main() {
std::vector<Point3D> points;
points.push_back(Point3D(-1., 2.));
points.push_back(Point3D( 2., -1.));
points.push_back(Point3D(-2., 0.));
using boost::bind;
std::sort(points.begin(), points.end(),
bind(&Point3D::x, _1) < bind(&Point3D::x, _2));
// points sorted by x coord
std::sort(points.begin(), points.end(),
bind(&Point3D::y, _1) < bind(&Point3D::y, _2));
// points sorted by y coord
}
What a shame std::tr1::bind does not support that. But of course, with a C++0x compiler you'll be able to do this:
std::sort(points.begin(), points.end(),
[](Point3D const & a, Point3D const & b) { return a.x < b.x; });
If you want to sort by x or y or z, those are three different functionalities. Which coordinate to sort by is extra information which doesn't really come from std::sort. You need have an object to pass it on.
struct coord_comparison {
int coord_id; // <= critical information
bool operator()( double (*l)[3], double (*r)[3] ) {
return (*l)[ coord_id ] < (*r)[ coord_id ];
}
coord_comparison( int id ) { coord_id = id; }
};
Create this struct inside your class or outside, but it needs to be a structure and not a free function, and operator() cannot be static. Call:
std::sort(points_vec.begin(), points_vec.end(), compare_points( 1 /*for y*/) );
Sorting by all 3 coords at once:
You have
std:vector<double*> points_vec;
I'm going to presume that the double* points to an array of 3 coordinates. This is cleaner:
std:vector<double(*)[3]> points_vec;
std::sort's third argument is a functor which compares two sequence objects:
bool compare_coords( double(*l)[3], double(*r)[3] ) {
Fortunately, comparing two sequences is already coded for you by std::less:
return std::less( *l, *l + ( sizeof *l/sizeof **l ), r );
(perhaps I did more work than necessary to get the size of the array)
return std::less( *l, *l + 3, r );
}
This function may be useful outside the class, so I'd make it a free function. You need to make it static if it's going to stay inside the class.
Finally, leave off the parens when passing the function to std::sort:
std::sort(points_vec.begin(), points_vec.end(), compare_points );
I'm using two 3rd party libraries, which both implement their own 2D vector class. Unfortunately, I have to work with both of them, so is there anyway I can write some "friend" functions so that one can automatically be converted to the other when I try to use them in functions from the other library?
Auto-cast seems not to be possible. You could define global conversion function and call it explicitly. Could you post definition of that classes? May be some trick with inheritance will be possible.
Something like this, but it is not auto-cast:
class T1 {};
class T2 {};
class UnionType : public T1, public T2
{
public:
UnionType( const T1& val ) {} // real storing should be here
UnionType( const T2& val ) {} // real storing should be here
operator T1() { T1 t; return t; } // real conversion should be here
operator T2() { T2 t; return t; } // real conversion should be here
};
int main()
{
T1 t;
T2 t2 = UnionType(t);
return 0;
}
Conversion operators have to be member functions.
In situations like this, I have used a convert<X,Y> function template, with full specialisations or overloads for each pair of types that I want to "cast". In this case, you wouldn't need the template, just two overloads, one in each direction, because for a given X there's only ever one thing you convert it to.
Then it's rarely any trouble to switch between one and the other (the notable exception being when you're using template code which requires that one parameter type be convertible to another). You can easily see in the code the boundary between the two APIs, without introducing much noise.
The reason I've had this situation a lot is writing OS abstraction layers - the underlying OS has one set of objects or opaque handles for various OS concepts, and the API you're implementing has another. It's much nicer to just "convert" from one set of concepts to the other, without having ConvertHostMutexToGuestMutex, ConvertGuestMutexToHostMutex, ConvertHostSocketOptsToGuestSocketOpts etc. The disadvantage is the usual one with widespread overloading, that it's not necessarily obvious where the functions are actually defined.
One way would be to derive from those classes and provide conversion operators for one another. But then you have to use the derived class objects through out your code. Here is some sample code:
class ThirdParty1
{
public:
ThirdParty1(int x, int y) : m_x(x), m_y(y)
{
}
int getX() const { return m_x; }
int getY() const { return m_y; }
private:
int m_x;
int m_y;
};
class ThirdParty2
{
public:
ThirdParty2(int x, int y) : m_x(x), m_y(y)
{
}
int getX() const { return m_x; }
int getY() const { return m_y; }
private:
int m_x;
int m_y;
};
template<class Type, class AdaptedType>
class TP1Adaptor : public Type
{
public:
TP1Adaptor(int x, int y): Type(x,y)
{
}
operator AdaptedType()
{
return AdaptedType(getX(),getY());
}
};
typedef TP1Adaptor<ThirdParty1, ThirdParty2> First2D;
typedef TP1Adaptor<ThirdParty2, ThirdParty1> Second2D;
void f(ThirdParty1 tp)
{
}
void f1(ThirdParty2 tp)
{
}
int main()
{
First2D f(0,0);
f1(f);
return 0;
}