Const initialization of an array of objects

Hello, I am trying to do a constant initialization of an array of "Vec3f" instances. Currently, I tried to implement it based on the code of a const initialization of an int array:

1
2
3
4
5
6
7
8
9
10
11
12
#include "Vec3f.h"
#include "GeometricObjects.h"

class BVolume {
   public:
      BVolume () {}
   private:
      Vec2f slabs [8];
      static const Vec3f normals [8];
      int min_triangle, max_triangle;
};
   const Vec3f BVolume::normals [8] = {{1,0,0},{0,1,0},{1,0,0},{0,1,0},{1,0,0},{0,1,0},{1,0,0},{0,1,0}};


where Vec3f it is a triple of floats with the following constructors:
1
2
3
4
5
6
class Vec3f {
   public:
      inline Vec3f () : x (0), y (0), z (0) {}
      inline Vec3f (const float xx, const float yy, const float zz) : x (xx), y (yy), z (zz)  { }
....
....


When I try to compile this code, this error shows up:

1
2
obj/Debug/Scene.o||In function `Vec3f':|
/media/34GB/demos/asmfrt/Vec3f.h|8|multiple definition of `BVolume::normals'|
where this line 8 is the one of the first Vec3f constructor .

So I am actually trying to implement a second constructor with the line const Vec3f BVolume::normals [8] = ...... ?. To what I shall change that so it doesn't make the compiler confused?
Static member data that is not inline must be defined exactly once, in one source file. In this case, constexpr implies inline.
static constexpr Vec3f normals [8] = { ... };
Last edited on
It did not work: /media/34GB/demos/asmfrt/BVolume.h|18|error: ‘constexpr’ does not name a type|
Obviously, to rely on inline variables, your compiler has to support C++17.

Instead, define the variable in exactly one source file. Look up any tutorial that teaches how to define static data members.

Also update your compiler.
Last edited on
I changed it to
1
2
static const Vec3f normals [7] = {{1,0,0},{0,1,0},{0,0,1},{SQRT3_3,SQRT3_3,SQRT3_3},{-SQRT3_3,SQRT3_3,SQRT3_3},
{-SQRT3_3,-SQRT3_3,SQRT3_3},{SQRT3_3,-SQRT3_3,SQRT3_3}};


and now it does not generates an error. Nonetheless, it generates an warning:
/media/34GB/demos/asmfrt/BVolume.h|19|warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x|

Shall I concern myself with it?
You should update your compiler.

You are using a version of C++ standardized in 1998. C++ has changed a lot in the past 22 years.
Ops, I talked to early, I am now receiving: /media/34GB/demos/asmfrt/Vec3f.h|32|undefined reference to `BVolume::normals'| . I tried to add -std=c++0x, but it appears to generate a compiler bug in file "vector.tcc"

/usr/include/c++/4.4/bits/vector.tcc|314|error: no match foroperator=’ in ‘__position.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = Bbox*, _Container = std::vector<Bbox, std::allocator<Bbox> >]() = ((const Bbox&)((const Bbox*)std::forward [with _Tp = const Bbox&](((const Bbox&)((const Bbox*)__args#0)))))’|

refering to line *__position = _Tp(std::forward<_Args>(__args)...);

About update the compiler, unfortunately I cannot do that.

What compiler do you use?
Does it have to be inside the class?
Otherwise you could define a global constant.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Vec3f {
public:
	inline Vec3f() : x(0), y(0), z(0) {}
	inline Vec3f(const float xx, const float yy, const float zz) : x(xx), y(yy), z(zz) { }

	float x, y, z;
};

class BVolume {
public:
	BVolume() {}
private:
	//Vec2f slabs[8];
	static const Vec3f normals[8];
	int min_triangle, max_triangle;
};

const Vec3f BVolume::normals[8] = {{1,0,0},{0,1,0},{1,0,0},{0,1,0},{1,0,0},{0,1,0},{1,0,0},{0,1,0}};


compiles Ok using VS.

About update the compiler, unfortunately I cannot do that.


What version are you using? If looks like you're using gcc which is free. The current version is 10.2 I really recommend that you update to the latest compiler version.
Last edited on
Yes, I found a solution just like you described seeplus. However, I am now facing "/media/34GB/demos/asmfrt/Vec3f.h|11|multiple definition of `BVolume::normals'|"

obj/Debug/RayTracer.o:/media/34GB/demos/asmfrt/RayTracer.cpp|376|first defined here|

This happens many times. How can I solve it?
Last edited on
[EDIT] misinterpreted
That is most likely due to the lack of include guards. See:

https://en.wikipedia.org/wiki/Include_guard

I.e. you should surround your header code like so:
1
2
3
4
5
6
#ifndef INCLUDEGUARD_...
#define INCLUDEGUARD_...

...

#endif 


Also you may use #pragma once which is supported by most compiler.
Last edited on
Yes, I actually have them:

1
2
#ifndef BVOLUME_H_INCLUDED
#define BVOLUME_H_INCLUDED 


#endif

Any suggestions?
Topic archived. No new replies allowed.