Exposing union's variables as class member variables [duplicate]
up vote
-2
down vote
favorite
This question already has an answer here:
Naming Array Elements, or Struct And Array Within a Union
4 answers
I've got this code that I just compiled successfully :
template <typename T, unsigned int N>
struct Vector
{
struct Vec1
{
T x;
};
struct Vec2 : public Vec1
{
T y;
};
struct Vec3 : public Vec2
{
T z;
};
struct Vec4 : public Vec3
{
T w;
};
template <unsigned int N>
union Data
{
std::array<T, N> components;
};
template <>
union Data<1>
{
Vec1 vec;
std::array<T, 1> components;
};
template <>
union Data<2>
{
Vec2 vec;
std::array<T, 2> components;
};
template <>
union Data<3>
{
Vec3 vec;
std::array<T, 3> components;
};
template <>
union Data<4>
{
Vec4 vec;
std::array<T, 4> components;
};
Data<N> data;
};
It works as intended, however I would like the struct Vector
to expose the data's variables as its own member variables.
Is it possible?
The solution would allow me to do Vector<int, 3> vec; vec.x ...; vec.components[0] ...;
The purpose of the union is to access easily both the vector's components as an array and individually.
Also, if you happen to know a better way to implement the templated union Data
specializations, please say so as I find it kinda hard coded. It would be perfect to recursively add variables without having to add the variables of the previous specialization.
For example, I would only need to declare T x
once.
c++ templates union
marked as duplicate by Baum mit Augen
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 25 at 20:17
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
|
show 11 more comments
up vote
-2
down vote
favorite
This question already has an answer here:
Naming Array Elements, or Struct And Array Within a Union
4 answers
I've got this code that I just compiled successfully :
template <typename T, unsigned int N>
struct Vector
{
struct Vec1
{
T x;
};
struct Vec2 : public Vec1
{
T y;
};
struct Vec3 : public Vec2
{
T z;
};
struct Vec4 : public Vec3
{
T w;
};
template <unsigned int N>
union Data
{
std::array<T, N> components;
};
template <>
union Data<1>
{
Vec1 vec;
std::array<T, 1> components;
};
template <>
union Data<2>
{
Vec2 vec;
std::array<T, 2> components;
};
template <>
union Data<3>
{
Vec3 vec;
std::array<T, 3> components;
};
template <>
union Data<4>
{
Vec4 vec;
std::array<T, 4> components;
};
Data<N> data;
};
It works as intended, however I would like the struct Vector
to expose the data's variables as its own member variables.
Is it possible?
The solution would allow me to do Vector<int, 3> vec; vec.x ...; vec.components[0] ...;
The purpose of the union is to access easily both the vector's components as an array and individually.
Also, if you happen to know a better way to implement the templated union Data
specializations, please say so as I find it kinda hard coded. It would be perfect to recursively add variables without having to add the variables of the previous specialization.
For example, I would only need to declare T x
once.
c++ templates union
marked as duplicate by Baum mit Augen
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 25 at 20:17
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
2
How are you planning to use thatunion
? You are aware that accessing anyunion
member that wasn't used for initialization is undefined behavior, no?
– πάντα ῥεῖ
Nov 19 at 17:43
2
What is the purpose of the union? If you are using it to access the individual elements of the array you are in for a surprise
– NathanOliver
Nov 19 at 17:44
1
@Thecheeselover The union won't give that to you. You'll have to specialize the entire class and use reference members to the array. Or you could provide functions that have the variable name, and use those as accessors.
– NathanOliver
Nov 19 at 17:47
1
compiled successfully - this code does not compile successfully also to access both vector components and array you will need to pack components into struct or only one of them can be active. Basically all you want to do is to add getters likeget_x
get_y
intostd::array
– VTT
Nov 19 at 17:47
1
@Fibbles Thestd::array
won't map properly to the otherunion
members anyways.
– πάντα ῥεῖ
Nov 19 at 17:52
|
show 11 more comments
up vote
-2
down vote
favorite
up vote
-2
down vote
favorite
This question already has an answer here:
Naming Array Elements, or Struct And Array Within a Union
4 answers
I've got this code that I just compiled successfully :
template <typename T, unsigned int N>
struct Vector
{
struct Vec1
{
T x;
};
struct Vec2 : public Vec1
{
T y;
};
struct Vec3 : public Vec2
{
T z;
};
struct Vec4 : public Vec3
{
T w;
};
template <unsigned int N>
union Data
{
std::array<T, N> components;
};
template <>
union Data<1>
{
Vec1 vec;
std::array<T, 1> components;
};
template <>
union Data<2>
{
Vec2 vec;
std::array<T, 2> components;
};
template <>
union Data<3>
{
Vec3 vec;
std::array<T, 3> components;
};
template <>
union Data<4>
{
Vec4 vec;
std::array<T, 4> components;
};
Data<N> data;
};
It works as intended, however I would like the struct Vector
to expose the data's variables as its own member variables.
Is it possible?
The solution would allow me to do Vector<int, 3> vec; vec.x ...; vec.components[0] ...;
The purpose of the union is to access easily both the vector's components as an array and individually.
Also, if you happen to know a better way to implement the templated union Data
specializations, please say so as I find it kinda hard coded. It would be perfect to recursively add variables without having to add the variables of the previous specialization.
For example, I would only need to declare T x
once.
c++ templates union
This question already has an answer here:
Naming Array Elements, or Struct And Array Within a Union
4 answers
I've got this code that I just compiled successfully :
template <typename T, unsigned int N>
struct Vector
{
struct Vec1
{
T x;
};
struct Vec2 : public Vec1
{
T y;
};
struct Vec3 : public Vec2
{
T z;
};
struct Vec4 : public Vec3
{
T w;
};
template <unsigned int N>
union Data
{
std::array<T, N> components;
};
template <>
union Data<1>
{
Vec1 vec;
std::array<T, 1> components;
};
template <>
union Data<2>
{
Vec2 vec;
std::array<T, 2> components;
};
template <>
union Data<3>
{
Vec3 vec;
std::array<T, 3> components;
};
template <>
union Data<4>
{
Vec4 vec;
std::array<T, 4> components;
};
Data<N> data;
};
It works as intended, however I would like the struct Vector
to expose the data's variables as its own member variables.
Is it possible?
The solution would allow me to do Vector<int, 3> vec; vec.x ...; vec.components[0] ...;
The purpose of the union is to access easily both the vector's components as an array and individually.
Also, if you happen to know a better way to implement the templated union Data
specializations, please say so as I find it kinda hard coded. It would be perfect to recursively add variables without having to add the variables of the previous specialization.
For example, I would only need to declare T x
once.
This question already has an answer here:
Naming Array Elements, or Struct And Array Within a Union
4 answers
c++ templates union
c++ templates union
edited Nov 19 at 18:55
asked Nov 19 at 17:38
Thecheeselover
195118
195118
marked as duplicate by Baum mit Augen
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 25 at 20:17
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by Baum mit Augen
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 25 at 20:17
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
2
How are you planning to use thatunion
? You are aware that accessing anyunion
member that wasn't used for initialization is undefined behavior, no?
– πάντα ῥεῖ
Nov 19 at 17:43
2
What is the purpose of the union? If you are using it to access the individual elements of the array you are in for a surprise
– NathanOliver
Nov 19 at 17:44
1
@Thecheeselover The union won't give that to you. You'll have to specialize the entire class and use reference members to the array. Or you could provide functions that have the variable name, and use those as accessors.
– NathanOliver
Nov 19 at 17:47
1
compiled successfully - this code does not compile successfully also to access both vector components and array you will need to pack components into struct or only one of them can be active. Basically all you want to do is to add getters likeget_x
get_y
intostd::array
– VTT
Nov 19 at 17:47
1
@Fibbles Thestd::array
won't map properly to the otherunion
members anyways.
– πάντα ῥεῖ
Nov 19 at 17:52
|
show 11 more comments
2
How are you planning to use thatunion
? You are aware that accessing anyunion
member that wasn't used for initialization is undefined behavior, no?
– πάντα ῥεῖ
Nov 19 at 17:43
2
What is the purpose of the union? If you are using it to access the individual elements of the array you are in for a surprise
– NathanOliver
Nov 19 at 17:44
1
@Thecheeselover The union won't give that to you. You'll have to specialize the entire class and use reference members to the array. Or you could provide functions that have the variable name, and use those as accessors.
– NathanOliver
Nov 19 at 17:47
1
compiled successfully - this code does not compile successfully also to access both vector components and array you will need to pack components into struct or only one of them can be active. Basically all you want to do is to add getters likeget_x
get_y
intostd::array
– VTT
Nov 19 at 17:47
1
@Fibbles Thestd::array
won't map properly to the otherunion
members anyways.
– πάντα ῥεῖ
Nov 19 at 17:52
2
2
How are you planning to use that
union
? You are aware that accessing any union
member that wasn't used for initialization is undefined behavior, no?– πάντα ῥεῖ
Nov 19 at 17:43
How are you planning to use that
union
? You are aware that accessing any union
member that wasn't used for initialization is undefined behavior, no?– πάντα ῥεῖ
Nov 19 at 17:43
2
2
What is the purpose of the union? If you are using it to access the individual elements of the array you are in for a surprise
– NathanOliver
Nov 19 at 17:44
What is the purpose of the union? If you are using it to access the individual elements of the array you are in for a surprise
– NathanOliver
Nov 19 at 17:44
1
1
@Thecheeselover The union won't give that to you. You'll have to specialize the entire class and use reference members to the array. Or you could provide functions that have the variable name, and use those as accessors.
– NathanOliver
Nov 19 at 17:47
@Thecheeselover The union won't give that to you. You'll have to specialize the entire class and use reference members to the array. Or you could provide functions that have the variable name, and use those as accessors.
– NathanOliver
Nov 19 at 17:47
1
1
compiled successfully - this code does not compile successfully also to access both vector components and array you will need to pack components into struct or only one of them can be active. Basically all you want to do is to add getters like
get_x
get_y
into std::array
– VTT
Nov 19 at 17:47
compiled successfully - this code does not compile successfully also to access both vector components and array you will need to pack components into struct or only one of them can be active. Basically all you want to do is to add getters like
get_x
get_y
into std::array
– VTT
Nov 19 at 17:47
1
1
@Fibbles The
std::array
won't map properly to the other union
members anyways.– πάντα ῥεῖ
Nov 19 at 17:52
@Fibbles The
std::array
won't map properly to the other union
members anyways.– πάντα ῥεῖ
Nov 19 at 17:52
|
show 11 more comments
1 Answer
1
active
oldest
votes
up vote
5
down vote
accepted
I think you need to bring some clarity to your design and the code.
Use of
template <>
union Data<3>
{
T x;
T y;
T z;
std::array<T, 3> components;
};
does not sound right. You need to have {x, y, z}
or components
, not x
, or y
, or z
, or components
. What you need is something along the lines of
template <>
union Data<3>
{
struct
{
T x;
T y;
T z;
} members;
std::array<T, 3> components;
};
Having said that, the cleanest member variable is just
std::array<T, N> components;
As far as the member variables are concerned, Vector
can be defined as:
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
};
If you need to expose the elements of components
through x
, y
, and z
-like abstractions, it will be better to add member functions.
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
T& x()
{
static_assert(N > 0);
return components[0];
}
T& y()
{
static_assert(N > 1);
return components[1];
}
T& z()
{
static_assert(N > 2);
return components[2];
}
};
with the above definition of Vector
, the following main
function should work.
int main()
{
Vector<int, 1> v1;
v1.x() = 20;
Vector<int, 2> v2;
v2.x() = 20;
v2.y() = 30;
Vector<int, 3> v3;
v3.x() = 20;
v3.y() = 30;
v3.z() = 40;
}
If you use
Vector<int, 2> v2;
v2.z() = 20;
you should get a compile-time error.
You can add the const
versions of the above functions to make the member functions work with const
objects too.
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
T& x()
{
static_assert(N > 0);
return components[0];
}
T const& x() const
{
static_assert(N > 0);
return components[0];
}
T& y()
{
static_assert(N > 1);
return components[1];
}
T const& y() const
{
static_assert(N > 1);
return components[1];
}
T& z()
{
static_assert(N > 2);
return components[2];
}
T const& z() const
{
static_assert(N > 2);
return components[2];
}
};
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
I think you need to bring some clarity to your design and the code.
Use of
template <>
union Data<3>
{
T x;
T y;
T z;
std::array<T, 3> components;
};
does not sound right. You need to have {x, y, z}
or components
, not x
, or y
, or z
, or components
. What you need is something along the lines of
template <>
union Data<3>
{
struct
{
T x;
T y;
T z;
} members;
std::array<T, 3> components;
};
Having said that, the cleanest member variable is just
std::array<T, N> components;
As far as the member variables are concerned, Vector
can be defined as:
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
};
If you need to expose the elements of components
through x
, y
, and z
-like abstractions, it will be better to add member functions.
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
T& x()
{
static_assert(N > 0);
return components[0];
}
T& y()
{
static_assert(N > 1);
return components[1];
}
T& z()
{
static_assert(N > 2);
return components[2];
}
};
with the above definition of Vector
, the following main
function should work.
int main()
{
Vector<int, 1> v1;
v1.x() = 20;
Vector<int, 2> v2;
v2.x() = 20;
v2.y() = 30;
Vector<int, 3> v3;
v3.x() = 20;
v3.y() = 30;
v3.z() = 40;
}
If you use
Vector<int, 2> v2;
v2.z() = 20;
you should get a compile-time error.
You can add the const
versions of the above functions to make the member functions work with const
objects too.
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
T& x()
{
static_assert(N > 0);
return components[0];
}
T const& x() const
{
static_assert(N > 0);
return components[0];
}
T& y()
{
static_assert(N > 1);
return components[1];
}
T const& y() const
{
static_assert(N > 1);
return components[1];
}
T& z()
{
static_assert(N > 2);
return components[2];
}
T const& z() const
{
static_assert(N > 2);
return components[2];
}
};
add a comment |
up vote
5
down vote
accepted
I think you need to bring some clarity to your design and the code.
Use of
template <>
union Data<3>
{
T x;
T y;
T z;
std::array<T, 3> components;
};
does not sound right. You need to have {x, y, z}
or components
, not x
, or y
, or z
, or components
. What you need is something along the lines of
template <>
union Data<3>
{
struct
{
T x;
T y;
T z;
} members;
std::array<T, 3> components;
};
Having said that, the cleanest member variable is just
std::array<T, N> components;
As far as the member variables are concerned, Vector
can be defined as:
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
};
If you need to expose the elements of components
through x
, y
, and z
-like abstractions, it will be better to add member functions.
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
T& x()
{
static_assert(N > 0);
return components[0];
}
T& y()
{
static_assert(N > 1);
return components[1];
}
T& z()
{
static_assert(N > 2);
return components[2];
}
};
with the above definition of Vector
, the following main
function should work.
int main()
{
Vector<int, 1> v1;
v1.x() = 20;
Vector<int, 2> v2;
v2.x() = 20;
v2.y() = 30;
Vector<int, 3> v3;
v3.x() = 20;
v3.y() = 30;
v3.z() = 40;
}
If you use
Vector<int, 2> v2;
v2.z() = 20;
you should get a compile-time error.
You can add the const
versions of the above functions to make the member functions work with const
objects too.
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
T& x()
{
static_assert(N > 0);
return components[0];
}
T const& x() const
{
static_assert(N > 0);
return components[0];
}
T& y()
{
static_assert(N > 1);
return components[1];
}
T const& y() const
{
static_assert(N > 1);
return components[1];
}
T& z()
{
static_assert(N > 2);
return components[2];
}
T const& z() const
{
static_assert(N > 2);
return components[2];
}
};
add a comment |
up vote
5
down vote
accepted
up vote
5
down vote
accepted
I think you need to bring some clarity to your design and the code.
Use of
template <>
union Data<3>
{
T x;
T y;
T z;
std::array<T, 3> components;
};
does not sound right. You need to have {x, y, z}
or components
, not x
, or y
, or z
, or components
. What you need is something along the lines of
template <>
union Data<3>
{
struct
{
T x;
T y;
T z;
} members;
std::array<T, 3> components;
};
Having said that, the cleanest member variable is just
std::array<T, N> components;
As far as the member variables are concerned, Vector
can be defined as:
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
};
If you need to expose the elements of components
through x
, y
, and z
-like abstractions, it will be better to add member functions.
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
T& x()
{
static_assert(N > 0);
return components[0];
}
T& y()
{
static_assert(N > 1);
return components[1];
}
T& z()
{
static_assert(N > 2);
return components[2];
}
};
with the above definition of Vector
, the following main
function should work.
int main()
{
Vector<int, 1> v1;
v1.x() = 20;
Vector<int, 2> v2;
v2.x() = 20;
v2.y() = 30;
Vector<int, 3> v3;
v3.x() = 20;
v3.y() = 30;
v3.z() = 40;
}
If you use
Vector<int, 2> v2;
v2.z() = 20;
you should get a compile-time error.
You can add the const
versions of the above functions to make the member functions work with const
objects too.
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
T& x()
{
static_assert(N > 0);
return components[0];
}
T const& x() const
{
static_assert(N > 0);
return components[0];
}
T& y()
{
static_assert(N > 1);
return components[1];
}
T const& y() const
{
static_assert(N > 1);
return components[1];
}
T& z()
{
static_assert(N > 2);
return components[2];
}
T const& z() const
{
static_assert(N > 2);
return components[2];
}
};
I think you need to bring some clarity to your design and the code.
Use of
template <>
union Data<3>
{
T x;
T y;
T z;
std::array<T, 3> components;
};
does not sound right. You need to have {x, y, z}
or components
, not x
, or y
, or z
, or components
. What you need is something along the lines of
template <>
union Data<3>
{
struct
{
T x;
T y;
T z;
} members;
std::array<T, 3> components;
};
Having said that, the cleanest member variable is just
std::array<T, N> components;
As far as the member variables are concerned, Vector
can be defined as:
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
};
If you need to expose the elements of components
through x
, y
, and z
-like abstractions, it will be better to add member functions.
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
T& x()
{
static_assert(N > 0);
return components[0];
}
T& y()
{
static_assert(N > 1);
return components[1];
}
T& z()
{
static_assert(N > 2);
return components[2];
}
};
with the above definition of Vector
, the following main
function should work.
int main()
{
Vector<int, 1> v1;
v1.x() = 20;
Vector<int, 2> v2;
v2.x() = 20;
v2.y() = 30;
Vector<int, 3> v3;
v3.x() = 20;
v3.y() = 30;
v3.z() = 40;
}
If you use
Vector<int, 2> v2;
v2.z() = 20;
you should get a compile-time error.
You can add the const
versions of the above functions to make the member functions work with const
objects too.
template <typename T, unsigned int N>
struct Vector
{
std::array<T, N> components;
T& x()
{
static_assert(N > 0);
return components[0];
}
T const& x() const
{
static_assert(N > 0);
return components[0];
}
T& y()
{
static_assert(N > 1);
return components[1];
}
T const& y() const
{
static_assert(N > 1);
return components[1];
}
T& z()
{
static_assert(N > 2);
return components[2];
}
T const& z() const
{
static_assert(N > 2);
return components[2];
}
};
edited Nov 19 at 19:02
answered Nov 19 at 18:04
R Sahu
164k1291184
164k1291184
add a comment |
add a comment |
2
How are you planning to use that
union
? You are aware that accessing anyunion
member that wasn't used for initialization is undefined behavior, no?– πάντα ῥεῖ
Nov 19 at 17:43
2
What is the purpose of the union? If you are using it to access the individual elements of the array you are in for a surprise
– NathanOliver
Nov 19 at 17:44
1
@Thecheeselover The union won't give that to you. You'll have to specialize the entire class and use reference members to the array. Or you could provide functions that have the variable name, and use those as accessors.
– NathanOliver
Nov 19 at 17:47
1
compiled successfully - this code does not compile successfully also to access both vector components and array you will need to pack components into struct or only one of them can be active. Basically all you want to do is to add getters like
get_x
get_y
intostd::array
– VTT
Nov 19 at 17:47
1
@Fibbles The
std::array
won't map properly to the otherunion
members anyways.– πάντα ῥεῖ
Nov 19 at 17:52