Aliasing glm::vec4 in class using union - c++

I want to enhance my AABB class in my raytracer by doing member variable aliasing(make AABB::min alias to AABB::bounds[0] and AABB::max alias to AABB::bounds[1])
This is the current AABB code.
class AABB
{
public:
//methods ignored...
float4 min;
float4 max;
};
To implement class member aliasing. I tried to use union to achieve it. Which makes the declaration of the variables looks like this.
union
{
float4 bounds[2];
struct {float4 min,max;};
};
But this gives me the following error message:
error: member ‘glm::float4 Incarnate::AABB::<anonymous union>::<anonymous struct>::min’ with constructor not allowed in anonymous aggregate
struct {float4 min,max;};
After searching on Google. I don't find any way to workaround this issue while still achieving my original goal of aliasing the variables. (All solutions I found will add complexity on accessing the variables.)
Is there anyway around this?
Note: float4 is glm::vec4. I used the GLM compatibility header so I could program like how I would in OpenCL.

Related

Memory Alignment Issue using Eigen library

I encountered a problem when I was using Eigen objects in my code. There is a class defined in my code:
class MyClass
{
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
MyClass();
/*other member functions*/
private:
float3 member_var;
Eigen::Matrix4f pose;
int id;
/*......*/
};
As the code is shown above, if pose is not the first member variable in MyClass, e.g. after float3 member_var, the program got segmentation fault ( core dumped) error.
If I put Eigen::Matrix4f pose as the first member variable, there is no segfault error.
I checked the documentation of Eigen library about memory alignment issues, see here.
It says that Eigen member variables are not required to be put at the beginning of the class.
I am wondering whether it is a bug from Eigen or my code?

Member Initialization in overloaded constructor

I have a basic semantic related doubt that I couldn't able to get clarified. Before stating the problem I will write down the minimum code to explain it clearly.
In Constants.hpp
#pragma once
enum class OpenglESVersion{
OES1,
OES2
};
In Cone.hpp, I have a enum member
OpenglESVersion esVersion;
Overloaded constructor definition in Cone.cpp that takes enum as parameter
Cone::Cone(const OpenglESVersion version) : rotationAngle(0), scale(1), esVersion(version) {}
Now in My RenderingEngine.cpp when i instantiate the Cone object:
Cone cone(OpenglESVersion::OES2);
I get syntax error:
No type named 'OES2' in 'OpenglESVersion'
Now If I update my object instantiaition to:
Cone cone{OpenglESVersion::OES2};
Now it works.
My complier is libc++[LLVM c++ standard library with c++ 11 support]
,and the dialect is c++11[-std=c++11]
I am using XCode.
Now coming to my doubt:
I went through resources to clarify the concept. In past I had use pre c++11 version in school following Bjarne's C++ programming Book which was printed in 2008, so that's why I didn't find this "curly" initialization syntax on the book for c++11 came out later.
I tried google and wasn't sure of what keyword to search but later the most common subject name pointed to "list initialization". Almost every resource covered on the advantage of this new syntax in c++11 but I never got clarified on why normal round bracket is treated as syntax error because there are many resource out there where example shows using rounder bracket too with combination of curly braces while explaining the difference but they were using examples of primitive types like:
int x(4);
int x{4};
So again this was not clarifying the concept for me. Now I am here to know or have some guidance to appropriate link or resource that explain my doubt.
Has my compiler made that round bracket intialization syntax
obsolete?
It's not obsolete but was never supported in c++?
I have declared and defined the overloaded constructor wrongly?
Is initialiation of member not supported via round bracket syntax?
and why?
EDIT:
This happens for any overloaded version, lets say int parameter overloaded version of constructor.
Cone::Cone(const int fooVariable) : fooMember(fooVariable){}
Only code works is:
Cone cone{8};
I get
Expected parameter declarator, Expected ')'
for Cone cone(8);
This behaviour doesn't happen if for curiosity I instantiate inside the member function of Cone class itself like the compiler doesn't thow any syntax or some error:
void Cone::Test(){
Cone cone(OpenglESVersion::OES2);
}
EDIT UPDATE 2:
I think I have another test case which should definitely narrow down. So here is the pattern:
class RenderingEngine
{
private:
Cone cone(OpenglESVersion::OES2);
};
So I am declaring and instantiating the Cone object as a member of RenderingEngine class. So could it be this that is causing my issue? Because If I do
Cone cone(OpenglESVersion::OES2);
inside any member function of RenderingEngine/Outside class implementation then it works. So There must be some basic rule that I am violating on what and how non-primitive member variable can be declared and instantiated.
Member initialization has been introduced in C++11.
Parenthesis are not supported to avoid the most vexing parse, so you can use {..} or = syntax:
class RenderingEngine
{
private:
Cone cone{OpenglESVersion::OES2};
};
or
class RenderingEngine
{
private:
Cone cone = Cone(OpenglESVersion::OES2); // With =, you can use parent on right side
};

Storing data of different types c++

I am working on a modular data logger that allows one to log data of different types. At the moment I made a File class that is a template. In order to declare an object of such a class one would do as such: File<double> f("filename.txt") or File<float> f("filename.txt"). I want to be able to store objects that were declared with double or float as template parameters in one vector. Is it possible to do something like that? I have tried a method online that uses a union as such:
union typ {
int int_dat;
double double_dat;
float float_dat;
}
and allows me to declare a vector as such: vector<File<typ> >. However, this gives me linker errors. Is there a easier, cleaner way to attempt this? The entire project in question is here
EDIT: follow up to this. How would one circumvent the issue surrounding the fact that if I conduct such operations:
std::vector<File<typ> > files;
File<typ> f("test.txt");
files.push_back(f);
files.at(0) << 35.4;
it causes a compile time error which I comprehended as what I'm guessing is: 35.4 is not of the type typ and cannot be used in the operation <<. How would one bypass such an error?
I think your vector of unions might have some issues. I haven't looked at your full code, but refer to this:
Questions about vector, union, and pointers in C++
The following should work (see http://codepad.org/TyrURyar)
#include <vector>
union type {
int int_dat;
double double_dat;
float float_dat;
};
template <typename T>
class Foo {
T t;
};
void foo2() {
std::vector<Foo<type> > x;
// NOTE: In pre-C++11, space is required between the >'s
}
Use Boost::Variant, if you can. It's a cleaner option. Unions can be used, but you should write and read from the same member if you don't want to end up with undefined behaviour i.e. it involves book keeping, which anyways Variant does for you automatically.

c++ using struct enum as a parameter won't compile

If create an enum inside a struct for readability, mentioned here
How to avoid name conflicts for two enum values with the same name in C++?
I am planning to add more enums, here and in other situations, I just wanted to know why the struct wasn't compiling. Coming from C# and Java I was hoping for a simpler syntax –
And have the struct as the parameter to a constructor in a class, I cannot call it from the main.cpp of a console application.
It gives me the error **no matching function for call toBarEnc::BarEnc(BarEnc::Scheme::eScheme)’ ** main.cpp
Here is the Class
class BarEnc {
public:
struct Scheme
{
enum eScheme
{ ADJ1M2, ADJ3M6
};
};
BarEnc();
BarEnc(BarEnc::Scheme scheme);
}
in main.cpp
I call it
BarEnc barEnc = BarEnc(BarEnc::Scheme::ADJ3M6);
But if I change the parameter to an int in the constructor the code compiles
BarEnc(int scheme);
If I change it to the enum the code compiles
BarEnc(BarEnc::Scheme::eScheme scheme);
But when it is a struct, it does not compile. I am relative new to C++, using GCC 4.6 to compile on Linux, using 99 standard.
Is there a reason why I can't use a struct as a parameter?
Simple question: how your enum value should be converted to struct?
Simple answer: there is no way, since there is no suitable constructor.
Your struct has no members, it has only type (enum), so, I have no idea, what you want to do.
When you declare the constructor as
BarEnc(BarEnc::Scheme scheme);
you tell the compiler that the BarEnc constructor takes a structure as argument, and so you can't pass the enumeration value as it's an enumeration and not the structure.
In this case there is really no use for a separate structure just to define the enumeration, you can declare it directly in the surrounding class:
class BarEnc {
public:
enum eScheme {
ADJ1M2,
ADJ3M6
};
BarEnc(eShceme scheme);
};
Then when creating BarEnc objects you pass the enumeration value:
BarEnc barenc(BarEnc::eScheme::ADJ1M2);
You can use a struct as parameter.
But your struct BarEnc::Scheme in fact has no member.
and the const value BarEnc::Scheme::ADJ3M6 's type is BarEnc::Scheme::eScheme, it cannot auto convert to a struct.

templates vs switch

I'm trying to find my ways in the C++ land and am increasingly confused by now. The toy application is a very basic OpenGL engine.
So here's the (I guess simple) problem:
I'd like to handle meshes of different vertex data, so I'd have e.g.
struct Vertex
{
Vector3f position;
}
struct VertexN : public Vertex
{
Vector3f normal;
}
Now I need a Mesh class, that holds the data and draws it.
I've tried something like this:
template<class T>
class Mesh
{
public:
Mesh();
~Mesh();
void load(const T * vertices, int num);
void draw();
protected:
T * vertices_;
};
The different vertices have to be loaded and drawn differently and this can be done with template specialization.
My problem is that I like to have another class that holds instances of Mesh objects, but templated class members are obviously not allowed.
The other solution I can think of is to hold pointers to the base struct Vertex in Mesh, pass an identifier for the Vertex type used and then use switch statements in load() and draw() to allow for the different implementations.
What is the best way to accomplish this?
Any help is greatly appreciated.
You can use inheritance and virtual functions. For example:
class MeshBase
{
public:
virtual ~MeshBase() { }
virtual void draw() = 0;
};
template <typename T>
class Mesh : public MeshBase
{
public:
virtual void draw() { }
// ...
};
With this approach, you can store pointers to the base class MeshBase in a container.
Ideally, you can use a pointer container, which will manage the pointers for you, or you can use a container of smart pointers (for example, a std::vector<std::shared_ptr<MeshBase> >, if your implementation includes shared_ptr; if not, it can be found in a number of places).
I would also recommend storing the vertices in a container in the Mesh class, rather than using manual dynamic allocation and memory management.
I recommend that you don't templatize your mesh class but make it capable of handling different types of vertex data. This is a common graphics problem and is addressed in DirectX with the notion of binding different "streams" of data together to draw geometry. In other words, your normals would be a different data stream than your position data. Then your mesh object becomes a container of multiple streams of data and would not be bound to a particular vertex format at compile time. I don't know OpenGL as well but I imagine there is a similar concept.
See: http://msdn.microsoft.com/en-us/library/bb147299(VS.85).aspx
#bshields has a point, you need to represent vertex data in the most efficient manner, which in the case of OpenGL are Vertex Buffer Objects (VBOs): http://www.opengl.org/wiki/Vertex_Buffer_Object
Given the guidelines exposed in the link above - which go in line with what #James McNellis says about not using inheritance for your Vertex types - and the fact that both loading and drawing will probably depend on the type of vertex and the kind of input (or output) I would suggest you to apply the Strategy pattern using static polymorphism, as outlined in the answer to this other question: template strategy pattern