Delphi absolute in C++ - c++

Is there an equivalent to Delphi's absolute in C++? I want to do the following:
// Structure A
struct A
{
double X;
double Y;
double Z;
}
// Structure B
struct B : A
{
double U absolute X;
double V absolute Y;
double W absolute Z;
}
I can use double & U = X in structure B but this will generate an additional pointer and change the size of the structure. Union is - I think - also not a solution, because structure B inherits structure A.
What I really want is to have access to the same memory by accessing for example X or U.

I like the idea of user2079303's answers, but want to inverse it.
Note - the question is named wrong and is violating "what is your real goal" or "show me your Z" rule. We do not need to mimic absolute keyword - it is total nonsense! we want to make pseudonyms for the record properties and use them interchangeably.
What I really want is to have access to the same memory by accessing for example X or U.
The quoted line is the ONLY line in the question that talks about the problem essence - making full pseudonyms.
So, let's start where user2079303 stopped and use the fact that C's unions do not have to be named, like it was used in https://stackoverflow.com/a/13624921/976391
So we just inverse the scopes.
/*union*/ struct coordinates {
/*struct*/ union {
double X;
double U;
};
/*struct*/ union {
double Y;
double V;
};
/*struct*/ union {
double Z;
double W;
};
};

Short version: There is no equivalent of the described language feature.
Long version C++:
There isn't an equivalent in C++. The member reference that you suggest gives you the same syntax, but indeed increases the size of the object.
Another close alternative is a member function, that returns a reference. That has no overhead (assuming inline expansion). A function call has different syntax than referencing a member though. But perhaps having identical syntax with member access is not important so this is what I suggest.
Long version C:
There is no inheritance in C at all, so there is nothing like the described "absolute" in it either.
we have several kinds of coordinates. Some of them are named x, y, z others (in another system) are named u, v, w.
Given this context, I would suggest a union (EDIT: It's better to swap the union and struct relation, see https://stackoverflow.com/a/41148089/2079303):
union coordinates {
struct {
float x, y, z;
} xyz;
struct {
float u, v, w;
} uvw;
};

If you want to interchangeably use XYZ and UVW, you can let each convert to the other.
// forward declare
struct B;
struct A
{
double X;
double Y;
double Z;
operator B() const;
}
struct B
{
double U;
double V;
double W;
operator A() const;
}
A::operator B() const { B b; b.U = X; b.V = Y; b.W = Z; return b; }
B::operator A() const { A a; a.X = U; a.Y = V; a.Z = W; return a; }

Related

How to cast one struct to another type with identical members?

If I'm given a struct variable like:
struct Quaternion {
float x;
float y;
float z;
float w;
}
But I need to call a function expecting a
struct Vector {
float x;
float y;
float z;
float w;
}
Is there a way in C++ to cast a variable of type Quaternion to type Vector?
You can write a converting constructor:
struct Quaternion {
float x;
float y;
float z;
float w;
explicit Quaternion(const Vector& vec) : x(vec.x),y(vec.y),z(vec.z),w(vec.w) {}
}
And similar for the other way.
In case you are looking for a way that does not require to copy the members, then I am not aware of a portable way to do that, and members having the same name does not help for that.
On the other hand, having same named members helps to write generic code like this:
template <typename T>
void foo(const T& t) {
std::cout << t.x << t.y << t.z << t.w;
}
You can call this with either a Quaternion or a Vector without needing to convert between them.
In case you cannot modify any existing code (not the structs nor the function you want to call), you can write a simple function to do the conversion (as suggested by ShadowRanger in a comment):
Vector Quat2Vect(const Quaternion& q) {
return {q.x,q.y,q.z,q.w};
}
If, as you said in a comment, you can't change to the two types, you could possibly "solve" the problem by using yet another type:
struct MyVector {
float x;
float y;
float z;
float w;
operator Quaternion() { return Quaternion{x, y, z, w}; }
operator Vector() { return Vector{x, y, z, w}; }
};
My advice: It's probably better to pick one or the other as the main type in your code and use a separate conversion function.
What I think you're hoping for, given that you specifically asked about "cast", is to use a cast to go from one to the other.
Vector v = {1, 2, 3, 4};
Quaternion* q = reinterpret_cast<Quaternion*>(&v);
do_something_with_quart(*q); // Could modify v if pass by reference
Strictly speaking, this is undefined behaviour, although it is overwhelmingly likely to work in practice, but I still wouldn't recommend it. If you're really desparate to do something cast like, it's legal to use memcpy so long as the member variables are the same type in the same order (and there are no virtual methods):
Vector v = {1, 2, 3, 4};
Quaternion q;
memcpy(&q, &v, sizeof(v));
do_something_with_quart(q);
memcpy(&v, &q, sizeof(v)); // Copy back any change
Although the language and documentation describes memcpy as a copying function, it has certain magical properties that often in practice make it identical to the previous block of code. But I would also strongly advise against this. I mean, yuck! Just look at it!!
This is just an addition to largest_prime_is_463035818's answer to point out that the members don't have to have the same name in order to write a generic function to use them. So long as there are an equal number of members, all are publicly accessible, and they have the same types, you can decompose objects with a structured-binding and use that.
template <typename T>
void foo(const T& t) {
auto const & [x, y, z, w] = t;
std::cout << x << y << z << w;
}

C++ Is there a way how to simulate union behavior between child and parent classes?

is there a way how to simulate union behavior? See following code:
// this is ideal interface, which I would like to simulate
struct IdealInterface{
union{
struct{float r,g,b;};
struct{float x,y,z;};
};
};
// this is real parent object I should not change
struct Parent{
float r, g, b;
};
// this interface has ok behavior,
// but sizeof(Child0) != sizeof(Parent)
// which causes problems
struct Child0:public Parent{
float & x, & y, & z;
Child0() : Parent(), x(r), y(g), z(b){ };
};
// this has ok size, but interface is different
struct Child1:public Parent{
float & x(){ return r; }
float & y(){ return g; }
float & z(){ return b; }
};
So as described, I should keep Parent class, and I should derive my child class from Parent. I should not create different types and play with the type conversions. Thus, is it possible to create derived class (form Parent) with the same interface as IdealInterface class has?
If you mean identical behavior to a union then no, not without actually using a union.
You could always just hide the underlying data:
class Vertex
{
Vertex();
Vertex(float,float,float);
float& x() { return r;}
float& y() { return g;}
float& z() { return b;}
float& r() { return r;}
float& g() { return g;}
float& b() { return b;}
void r(float rComponent) { this->r = rComponent; }
...
private:
float r, g, b;
}
However, the downside to this approach is you must call the methods vs. accessing the underlying variable like you can do with the union.
If you want:
Vertex v;
v.x = 1.0f
Then you would want to use a union.
Answer:
Firstly, I have some words for commentators. I asked a pretty straight question. What I got? For example answers about sizeof properties, which were not posed (btw, yeah in this case I have guarantee about sizeof - this is c++, not a kind of today common wild language).
Why I cannot use IdealInterface. Problem is more complex. I want to edit bigger pack of code with introduced constraints and dependencies. Thus this is the question and I cannot redefine question, however it implies simpler solution.
Answer: NO, it is not possible.
Why? It is based on properties of anonymous structs and unions.
Nearest approach: For my purpose, nearest approach is to use memory model as parameter.
struct BASIC_MEMORY_MODEL{
float x, y, z;
BASIC_MEMORY_MODEL() :x(), y(), z(){}
};
struct ADVANCED_MEMORY_MODEL{
union{
struct { float x, y, z; };
struct { float r, g, b; };
};
ADVANCED_MEMORY_MODEL() :x(), y(), z(){}
};
template<typename MEMORY_MODEL = BASIC_MEMORY_MODEL>
struct ParentBase : public MEMORY_MODEL{};
typedef ParentBase<> Parent;
struct Child : public ParentBase < ADVANCED_MEMORY_MODEL > {};

Member variable aliasing in a simple struct using union

I have a simple point struct that I would like to inherit:
struct PointXYZ
{
double x, y, z;
};
class extendedPoint : public PointXYZ
{
public:
double getXYZ(int i);
void setXYZ(int i, double value);
private:
int moreproperties;
};
The get-set function is indexed because I'd like to be able to loop through getting and setting the xyz values. I'd like to link the concept of indexed xyz and standalone x,y,z by modifying my base class as described in the answer to this post:
struct PointXYZ
{
union {
struct {
double x, y, z;
};
double xyz[3];
};
};
class extendedPoint : public PointXYZ
{
public:
double getXYZ(int i) { return xyz[i]; }
void setXYZ(int i, double value) { xyz[i] = value; }
private:
int moreproperties;
};
But this post directly contradicts the first post on whether the following is valid:
double dostuff()
{
PointXYZ p;
p.x = 123.88;
return p.xyz[0];
}
So, is PointXYZ's use of union valid c++ and consistent between compilers or not?
From the standard:
In a union, at most one of the non-static data members can be active at any time, that is, the value of at
most one of the non-static data members can be stored in a union at any time. [ Note: One special guarantee
is made in order to simplify the use of unions: If a standard-layout union contains several standard-layout
structs that share a common initial sequence (9.2), and if an object of this standard-layout union type
contains one of the standard-layout structs, it is permitted to inspect the common initial sequence of any of
standard-layout struct members; see 9.2. — end note ]
Seems to me that the special guarantee indicates that
struct PointXYZ {
union {
struct {
double xyz[3];
};
struct {
double x, y, z;
};
};
};
should work just fine when reading the member that was not last written (See it happen).
Note, however, that according to the specs, your example of
struct PointXYZ {
union {
struct {
double xyz[3];
};
double x, y, z;
};
};
is undefined behaviour when reading the member that was not last written (See it happen). When setting xyz[0], xyz[1] and xyz[2], all of x, y and z have the same value as xyz[0] in the linked example. I would expect most compilers to behave like this, but the standard does not guarantee it.
struct PointXYZ {
union {
double xyz[3];
struct {
double x, y, z;
};
};
};
Depending on the compiler / platform, you may have data alignment issues (it's possible though unlikely).
x, y, z may not reside in memory in correspondence with xyz[0], xyz[1], xyz[2].
C++ guarantees that elements of the xyz array are laid out contiguously, but it only guarantees that the address of an element of the struct is greater than the address of all earlier-declared elements (of course many compilers offer #pragma to control packing and alignment).
About the type punning matter (the practice of reading from a different union member than the one most recently written to)...
you could say that this isn't type punning (types match, so there is no pun, it's merely aliasing), but still, from an the viewpoint of the language standard, the member written to and read from are different, which is undefined in C++.
Anyway, generally, you'll have the expected result...
With GCC it's even guaranteed to work (even with -fstrict-aliasing):
Type punning
A member of a union object is accessed using a member of a different type
As a side note consider that anonymous unions are permitted but C++ prohibits anonymous structs (a lot of compilers allow them).
What about the following solution?
class PointXYZ
{
public:
double getXYZ(unsigned i) { return xyz[i]; }
void setXYZ(unsigned i, double value) { xyz[i] = value; }
double &x() { return xyz[0]; }
double &y() { return xyz[1]; }
double &z() { return xyz[2]; }
private:
double xyz[3];
};

Regarding struct initialization in c++

I have Struct like these
typedef struct sample
{
double x,
double y,
double z
}s1;
s1 s;
will the content in s variable initialized or not?
What will be the values of x,y,z?
thanks
x, y and z won't be initialized if s is defined in a function scope. They would be containing some unspecified values. At file scope the data members would be initialized to their default values.
In C++ however you can have a constructor initializer list to initialize the data members
For example
struct ABC
{
int x;
int y;
ABC(): x(1),y(2){}
};
ABC s; // x and y initialized to 1 and 2 respectively
In C++ you also have default initialization and value initialization to initialize data members.
In the code you presented, the fields will be uninitialized. You can add a constructor (if you need/can), or in case you need the POD-ness (some part of your code depends on some of those properties) and you cannot add a constructor, you can still value-initialize the struct (i.e. set each member to 0) at the place of use:
struct sample // typedef not required
{
double x,
double y,
double z
};
sample s = sample(); // will set all members to 0.0
Now, if you want to initialize different members with some particular values, because it is an aggregate you can use aggregate initialization:
sample s = { 1.0, 3.0 };
That will set x to 1.0, y to 3.0. Since there is no value for z, the compiler will set it to 0.0. Note that this means that sample s = {}; is equivalent to sample s = sample();
If it is C++, you could make constructor.
struct s1
{
s1( const double x = 0.0, const double y = 0.0, const double z = 0.0 )
: x(x), y(y), z(z)
{
};
double x;
double y;
double z;
};
s1 s;
Built-in types like double and int are initialised if the variable is static or at namespace/file scope, otherwise - for efficiency reasons - they're not initialised unless a constructor indicates that's useful.
Note: this answer addresses the "s1 s;" situation you describe. It is possible to provide an explicit initialisation when defining the variable, but that's another case.
To add a constructor so:
struct X
{
X() : x_(0), y_(0), z_(0) { }
double x, y, z;
};

C++ union array and vars?

There's no way to do something like this, in C++ is there?
union {
{
Scalar x, y;
}
Scalar v[2];
};
Where x == v[0] and y == v[1]?
Since you are using C++ and not C, and since they are of the same types, why not just make x a reference to v[0] and y a reference to v[1]
How about
union {
struct {
int x;
int y;
};
int v[2];
};
edit:
union a {
struct b { int first, second; } bee;
int v[2];
};
Ugly, but that's more accurate
Try this:
template<class T>
struct U1
{
U1();
T v[2];
T& x;
T& y;
};
template<class T>
U1<T>::U1()
:x(v[0])
,y(v[1])
{}
int main()
{
U1<int> data;
data.x = 1;
data.y = 2;
}
I've used something like this before. I'm not sure its 100% OK by the standard, but it seems to be OK with any compilers I've needed to use it on.
struct Vec2
{
float x;
float y;
float& operator[](int i) { return *(&x+i); }
};
You can add bounds checking etc to operator[] if you want ( you probably should want) and you can provide a const version of operator[] too.
If you're concerned about padding (and don't want to add the appropriate platform specific bits to force the struct to be unpadded) then you can use:
struct Vec2
{
float x;
float y;
float& operator[](int i) {
assert(i>=0);
assert(i<2);
return (i==0)?x:y;
}
const float& operator[](int i) const {
assert(i>=0);
assert(i<2);
return (i==0)?x:y;
}
};
I was looking for a similair thing and eventually came up with a solution.
I was looking to have a data storage object that I could use as both an array of values and as individual values (for end-user flexibility in writing Arduino libraries).
Here is what I came up with:
class data{
float _array[3];
public:
float& X = _array[0];
float& Y = _array[1];
float& Z = _array[2];
float& operator[](int index){
if (index >= 3) return _array[0]; //Make this action whatever you want...
return _array[index];
}
float* operator&(){return _array;}
};
int main(){
data Test_Vector;
Test_Vector[0] = 1.23; Test_Vector[1] = 2.34; Test_Vector[2] = 3.45;
cout<<"Member X = "<<Test_Vector.X;
cout<<"Member Y = "<<Test_Vector.Y;
cout<<"Member Z = "<<Test_Vector.Z;
float* vector_array = &Test_Vector;
cout<<"Array = {"<<vector_array[0]<<", "<<vector_array[1]<<", "<<vector_array[2]<<"}";
}
Thanks to Operator overloading, we can use the data object as if was an array and we can use it for pass-by-reference in function calls (just like an array)!
If someone with More C++ experience has a better way of applying this end product, I would love to see it!
EDIT: Changed up the code to be more cross-platform friendly
Given your example:
union
{
struct
{
Scalar x, y;
};
Scalar v[2];
};
As others have noted, in general, the standard does not guarantee that there will be no padding between x and y, and actually compilers inserting padding in structures is pretty common behavior.
On the other hand, with solutions like:
struct U
{
int v[2];
int& x;
int& y;
};
U::U()
: x(v[0])
, y(v[1])
{}
what I don't like mainly is the fact that I have to mention x, y twice. For cases where I have more than just a few elements (say 10), this becomes much less readable and harder to maintain - e.g. if you want to change the order of x,y then you have to change the indexes below too (well not mandatory but otherwise order in memory wouldn't match order of fields, which would not be recommended). Also, U can no longer be a POD since it needs a user-defined constructor. And finally, the x & y references consume additional memory.
Hence, the (acceptable for me) compromise I've come up with is:
struct Point
{
enum CoordType
{
X,
Y,
COUNT
};
int coords[CoordType::COUNT];
};
typedef Point::CoordType PtCoord;
With this you can then do:
Point p;
for ( int i = 0; i < PtCoord::COUNT; i++ )
p.coords[i] = 100;
std::cout << p.coords[PtCoord::X] << " " << p.coords[PtCoord::Y] << std::endl;
// 100 100
A bit sophisticated but I prefer this over the references suggestion.
Depending on what "Scalar" is, yes, you can do that in C++. The syntax is almost exactly (maybe even exactly exactly, but I'm rusty on unions) what you wrote in your example. It's the same as C, except there are restrictions on the types that can be in the unions (IIRC they must have a default constructor). Here's the relevant Wikipedia article.
With C++11 you have anonymous unions and structs which just export their definitions to the enclosing scope, so you can do this:
typedef int Scalar;
struct Vector
{
union
{
struct
{
Scalar x, y;
};
Scalar v[2];
};
};