struct type conversion

A current project using multiple libraries has at least two definitions of essentially the same struct

struct CvPoint {
int x, y;
};

struct Vector2i {
int x, y;
};

Often we have a variable of one type but need to pass it to a function that takes the other type so the compiler barks "cannot convert parameter..."
What's the best way to deal with this? pointer casting, overloaded cast??
If its within your power, your best bet would be to standardize on a single class but I am guessing this is beyond your control.

The answer to your question though is depends. Real helpful answer eh? ;)


If there is every any possibility the object you are dealing with isn't going to be of the type you expect it to be, you should use dynamic_cast. Otherwise a standard cast or static_cast will do the trick. Unlike a dynamic_cast a static_cast performs no runtime checks so it will perform a bit faster. Then again, a dynamic_cast will return null if the object being casted isn't actually what you say it is, while a static_cast will simply blow up in spectacular fashion, so be sure you are dealing with the object type you expect. A standard cast is like a static_cast with even less restrictions.

Oh, one last gotcha, dynamic_cast depends on RTTI being enabled, which this days will generally not be an issue, but it is one of those things to be aware of.
Last edited on
One way to solve this might be to define your own type with conversion operators for each type you need to use:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>

struct CvPoint {
int x, y;
};

struct Vector2i {
int x, y;
};

struct TwoVec
{
	int x, y;

	operator CvPoint()
	{
		CvPoint p;
		p.x = x;
		p.y = y;
		return p;
	}

	operator Vector2i()
	{
		Vector2i p;
		p.x = x;
		p.y = y;
		return p;
	}
};

void func1(const CvPoint& p)
{
	std::cout << p.x << ", " << p.y << '\n';
}

void func2(const Vector2i& p)
{
	std::cout << p.x << ", " << p.y << '\n';
}

int main()
{
	TwoVec t;

	t.x = 3;
	t.y = 4;

	func1(t);
	func2(t);
}
Only downside to that that is you will end up doubling up every non-templated interface, which depending on the code, could get annoying very fast.
My favorite solutions I have found so far are:

pointer casting

*(CvPoint*)&someVector2iVariable

anonymous unions

union {
CvPoint a;
Vector2i b;
};

Any comments?
Both are unsafe. The only safe way to do it would be to convert by copying to a new object (either implictily or explicitly).

1
2
3
4
5
6
7
8
9
// pick a better name than NameMe:
CvPoint NameMe(const Vector2i& v) { return CvPoint(v.x,v.y); }
Vector2i NameMe(const CvPoint& v) { return Vector2i (v.x,v.y); }


Vector2i example;

// pass 'example' to a function that takes a CvPoint:
SomeFunction( NameMe(example) );
Topic archived. No new replies allowed.