Home > Mobile >  C : Initialize struct with incomplete type
C : Initialize struct with incomplete type

Time:08-04

I have two types defined in a header file like so:

struct vec2{
    float x;
    float y;
    vec2() : x(0), y(0) {}
};
struct vec3{
    float x;
    float y;
    float z;
    vec3() : x(0), y(0), z(0) {}
};

In some C file I would like to be able to write:

vec2 a2 = {2,4};
vec3 a3 = vec2(a2);
//This would give me a3 with a z-value of 0.

Which would work by adding this to the header:

 vec3(vec2 a) : x(a.x), y(a.y), z(0) {}

But I would also like to be able to write:

vec3 a3 = {1,2,4};
vec2 a2 = vec3(a3); //Where this would result in a3's z component being dropped.

Is this possible? Would I need to typedef it somehow so the compiler knows ahead of time what size the 2 structures are?

CodePudding user response:

No problem, you have to set the constructors up to perform implicit conversions:

namespace vec{ // if in a header, this should avoid possible name conflicts
    struct vec3;   // forward declaration

    struct vec2{
        float x;
        float y;
        vec2(float inp1 = 0, float inp2 = 0): 
            x(inp1), y(inp2) {}
        vec2(const vec3& inp);   // vec3 forward declared
    };

    struct vec3{
        float x;
        float y;
        float z;
        vec3(float inp1 = 0, float inp2 = 0, float inp3 = 0): 
            x(inp1), y(inp2), z(inp3) {}
        vec3(const vec2& inp): 
            x(inp.x), y(inp.y), z(0) {}
    };

    vec2::vec2(const vec3& inp): 
        x(inp.x), y(inp.y) {}
}

Test function:

int main()
{
    using namespace vec;
    vec3 a = {1,2,3};
    vec2 a_minus(a);
    vec3 a_again(a_minus);
    
    std::cout << a_minus.x << ", " << a_minus.y << ", " << a_again.z <<'\n';

    return 0;
}

Output:

1, 2, 0

CodePudding user response:

You can do something like:

// Forward-declaration
struct vec2;
struct vec3;

struct vec2{
    float x;
    float y;
    vec2() : x(0), y(0) {}
    vec2(const vec3 &v3) : x(v3.x), y(v3.y) {}
};

struct vec3{
    float x;
    float y;
    float z;
    vec3() : x(0), y(0), z(0) {}
    vec3(const vec2 &v2) : x(v2.x), y(v2.y), z(0) {}
};

Note: This should also be separated into a header and source file (see Separating class code into a header and cpp file)

  • Related