【问题标题】:Initialization of constant structures, classes and arrays in namespace命名空间中常量结构、类和数组的初始化
【发布时间】:2016-03-20 13:16:04
【问题描述】:

我想创建命名空间Solids,它只存储有关几个常见实体(如platonic solids)的顶点和边/面连接性的信息。

于是我做了这个头文件Solids.h:

#ifndef  Solids_h
#define  Solids_h

#include "Vec3.h" // this is my class of 3D vector, e.g. class Vec3d{double x,y,z;}

namespace Solids{

    struct Tetrahedron{
        const static int    nVerts = 4;
        const static int    nEdges = 6;
        const static int    nTris  = 4;
        constexpr static Vec3d verts [nVerts]    = { {-1.0d,-1.0d,-1.0d}, {+1.0d,+1.0d,-1.0d}, {-1.0d,+1.0d,+1.0d}, {+1.0d,-1.0d,+1.0d} };
        constexpr static int   edges [nEdges][2] = { {0,1},{0,2},{0,3}, {1,2},{1,3},{2,3} };
        constexpr static int   tris  [nTris ][3] = { {0,1,2},{0,1,3},{0,2,3},{1,2,3} };
    } tetrahedron;

};

#endif

然后在我的包含Solids.h 的程序中,我想像这样绘制它:

void drawTriangles( int nlinks, const int * links, const Vec3d * points ){
    int n2 = nlinks*3;
    glBegin( GL_TRIANGLES );
    for( int i=0; i<n2; i+=3 ){
        Vec3f a,b,c,normal;
        convert( points[links[i  ]], a ); // this just converts double to float verion of Vec3
        convert( points[links[i+1]], b );
        convert( points[links[i+2]], c );
        normal.set_cross( a-b, b-c );
        normal.normalize( );
        glNormal3f( normal.x, normal.y, normal.z );
        glVertex3f( a.x, a.y, a.z );
        glVertex3f( b.x, b.y, b.z );
        glVertex3f( c.x, c.y, c.z );
    }
    glEnd();
};

// ommited some code there
int main(){
   drawTriangles( Solids::tetrahedron.nTris, (int*)(&Solids::tetrahedron.tris[0][0]), Solids::tetrahedron.verts );
}

但是,当我这样做时,我得到undefined reference to Solids::Tetrahedron::verts。这可能与这个undefined-reference-to-static-const-int 问题有关。

所以我想解决方案应该是在namespace{}struc{} 声明之外初始化它?

喜欢:

Solids::Tetrahedron::tris [Solids::Tetrahedron::nTris ][3] = { {0,1,2},{0,1,3},{0,2,3},{1,2,3} };

或:

Solids::Tetrahedron.tris [Solids::Tetrahedron.nTris ][3] = { {0,1,2},{0,1,3},{0,2,3},{1,2,3} };

没有更优雅的解决方案吗?

【问题讨论】:

  • 为什么首先需要这个结构?
  • 如果您的意思是不需要将数组打包到结构中,那是真的。基本上只是为了使名称更系统和可读性写Tetrahedon.verts而不是Tetrahedon_verts
  • 您在每个包含标题的文件中重新定义了Solids::tetrahedron,这违反了单一定义规则。
  • 你需要从定义中去掉tetrahedron这个词;改用Solids::Tetrahedron::nTris
  • 您已经定义了一个没有非静态成员的结构。这就是命名空间的用途。

标签: c++ c++11 namespaces initialization constants


【解决方案1】:

您可以使用 constexpr 静态成员函数,而不是使用 constexpr 数据成员。

struct Tetrahedron{
    constexpr static int    nVerts = 4;
    constexpr static int    nEdges = 6;
    constexpr static int    nTris  = 4;
    constexpr static Vec3d[nverts] verts() { return { {-1.0d,-1.0d,-1.0d}, {+1.0d,+1.0d,-1.0d}, {-1.0d,+1.0d,+1.0d}, {+1.0d,-1.0d,+1.0d} }; }
    constexpr static int[nEdges][2] edges() { return { {0,1},{0,2},{0,3}, {1,2},{1,3},{2,3} }; }
    constexpr static int[nTris ][3] tris() { return { {0,1,2},{0,1,3},{0,2,3},{1,2,3} }; }
} tetrahedron;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-17
    • 2011-06-04
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多