#Having trouble understanding std::vector and typedef

163 messages · Page 1 of 1 (latest)

versed harbor
#

So I am trying to do the following:

    typedef struct {
        float x, y;
    } k_vec2;

    typedef k_vec2 k_Triangle[3];

    k_Triangle t;
    t[0] = {1, 1};
    t[1] = {2, 1};
    t[2] = {3, 1};
 
    std::vector<k_Triangle> ts;
    ts.push_back(t);

And I'm getting the following errors that I don't quite understand:

C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xmemory(730): error C2672: 'std::construct_at': no matching overloaded function found
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xutility(461): note: could be '_Ty *std::construct_at(_Ty *const ,_Types ...) noexcept(<expr>)'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xmemory(730): note: the associated constraints are not satisfied
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xutility(459): note: '<unnamed-symbol>': initialization requires a brace-enclosed initializer list
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xutility(459): note: 'anonymous struct or union': initialization requires a brace-enclosed initializer list
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xutility(459): note: 'initializing': cannot convert from 'const k_vec2 [3]' to 'float'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xutility(459): note: There is no context in which this conversion is possible
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\include\xmemory(730): note: the template instantiation context (the oldest one first) is

Any help would be very much appreciated.

desert vaporBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

twin dawn
#
struct k_vec2{
  float x, y;
};
#

this is enough

#

also

#
using k_Triangle = k_vec[3];
#

this is what you meant probably

#

there is no reason to ever use typedef in C++ code 👍

twin dawn
versed harbor
#

Yeah I'm kinda straddling the line.... I just used some std containers, the rest of my code is pure C, I just dont like having to manage that stuff. Mixing it like that probably isnt smart.

twin dawn
#

but the best would be

struct k_Triangle{
  k_vec2 a;
  k_vec2 b;
  k_vec2 c;
};
versed harbor
#
typedef struct {
    union {
        float raw[2];
        struct {
            float x, y;
        };
        struct {
            float u, v;
        };
    };
} k_vec2;
#

that is my actual struct I just couldnt fit it in the limit

twin dawn
versed harbor
#

cool cool

twin dawn
#

struct k_vec2 is enough

twin dawn
#

it is valid in C i think

#

but not in C++

#
k_vec2 v{{1, 2}};
auto x = v.u;

i think it is UB

versed harbor
#

I looked at how other people did it and just did a minimal version of it. glm, cglm

twin dawn
#

maybe it is some special rule hmmm

#

i never really used unions, but i know the SDL library relies on something similar and it is UB in C++

versed harbor
#

It does cause problems with function overloading I noticed

#

if a function has a vec2 in one and a vec 3 in another calling it with {0, 1} as an argument for example produces an error,

twin dawn
versed harbor
#

you have to specify

#

vec2{0,1}

weak elbow
#

because to compile your codebase, you need at least one c++ compiler at some point to handle the container/std::vector

versed harbor
#

its just my style honestly, I'm here to get better. I'll likely not be using a C compiler with a C standard as there are some features i like, but im def using a subset. I'm not married to the typedef syntax

weak elbow
#

so either the whole project is basically a c++ one with strong c style, or it mixes a c++ part which was designed to interop with a c project through a c interface

versed harbor
#

I was really curious why it causes an error with the templates though

#

for the record I'm writing all of this to learn trig/line alg

weak elbow
#

vectors can't store arrays basically

twin dawn
#

but then again

weak elbow
#

that's not an array :p

twin dawn
#

you shoudl use a struct for the triangle probably

twin dawn
weak elbow
#

basically in the way vector works, .push_back needs to copy the element

#

and arrays are not copyable

versed harbor
#

yeah I used vector<vector<k_vec2>> when i eas developing the algo, i was just tyring to clean it up

#

That makes sense

#

but I didnt know it was a limitation

weak elbow
#

and by copyable I really mean array_type destination_variable = source_variable;

twin dawn
#

ofc not counting the actual std array implementation

weak elbow
#

I don't really agree with that but in beginner contexts it is definitely confusing

twin dawn
#

std array and std span solves almost all problems where you needed a C array

weak elbow
#

builtin arrays have benefits over std::array

versed harbor
#

yeah I dont know what else to say. I dont find most of c++ helpful in making things.... I just like having a dynamic array and a hash map

weak elbow
#

just, generally not worth the hassle if you don't know the fine print differences of how arrays behave with the rest of the language

weak elbow
versed harbor
#

fwiw the algo works (polygon triangulation) it just looks like crap.

weak elbow
#

anonymous struct's aren't a thing in c++, I forgot if they are a thing in c

#

plus the aliasing bit between union members

twin dawn
versed harbor
#

just default shorthand for texture coords

#

its really not needed

twin dawn
versed harbor
#

but typing x y z in color functions etc just made it less clear imho

twin dawn
#

sounds like they are very distinct types anyways 🤔

versed harbor
#

I looked at other libs and thats how they did it

#

they are not. they are just floats to be uploaded to the gpu

weak elbow
#

random remark but I'm fairly certain you'd still just do

typedef union {
  float raw[2];
  struct {
      float x, y;
  };
  struct {
      float u, v;
  };
} k_vec2;

though that doesn't solve any of the ub/extension bits

weak elbow
twin dawn
#

so does sdl

versed harbor
#

yeah it wasnt an appeal to authority

#

just i "copied" it

twin dawn
#

UV represents texture coordinates

#

RGB represents a color

#

XY(Z) represents a position

weak elbow
#

this is generally mightily inconvenient at the lower layers of architecture however

versed harbor
#

I have never used anything graphics related that made different vector types for different uses

weak elbow
#

hardware stuff cares more about the "raw data" and how to transmit that raw data across, than the type

twin dawn
#

you can always provide an explicit conversion operator to vec3 to use with glm

weak elbow
#

but your layers in cpu code doesn't have to abide by that

twin dawn
#
struct color{
  float r, g, b;
  explicit operator glm::vec3() const{
    return glm::vec3(r, g, b);
  }
};
#

this way you can still pass the color to glm, you just have to cast to vec3 first

#

implicit conversions in general are a horrible thing

versed harbor
#

here is the thing I'm all for just dropping it and using just float x, y;

twin dawn
#

they create so many bugs

versed harbor
#

here is the thing.... I'm using the same thing for matrix math 🙁

#

and that makes it so much worse

twin dawn
#

just has the problem of being able to convert a position to a color by accident

versed harbor
#
typedef struct {
    union {
        float raw[9];
        struct {
            k_vec3 c0, c1, c2;
        };
        struct {
            float m00, m01, m02;
            float m10, m11, m12;
            float m20, m21, m22;
        };
    };
} k_mat3;
desert vaporBOT
#

@versed harbor

It looks like you may have code formatting errors in your message

Note: Make sure to use back-ticks (`) and not quotes (')
Note: Make sure to specify a highlighting language, e.g. `cpp`, after the back-ticks

Markup

```cpp
int main() {}
```

Result
int main() {}
versed harbor
#

this makes writing and testing matrix operations so much easier.....

weak elbow
twin dawn
#

hear me out

#
using mat3 = std::array<std::array<float, 3>, 3>;
weak elbow
#

well I don't like that either :p

twin dawn
#

then you can just
m[0][0];

weak elbow
#

but I hear you, making a good and ergonomic linear algebra library is quite annoying

versed harbor
#

just doing a non-for looped mult function with the std::array one above is like 200 more []

weak elbow
#

a "non-for looped mult function"?

versed harbor
#

you can do matrix mult in loops but it was a lot slower, so i did it by hand, and ofc to eventually use sse intrinsics

#

From what i saw in libs they also type out the whole operation

#

none of the libs I investigated did any matrix operations with loops etc

#

either way, the take away is you cant use c style arrays with std containers, my style sucks, and large popular libs rely on UB

twin dawn
# weak elbow well I don't like that either :p

well my best shot at it would be

#include <cstddef>
#include <span>
#include <array>
#include <print>

template<typename T, std::size_t N>
class mat_t{
  std::array<T, N*N> data{};
public:
  constexpr auto size() const { return N; }
  T& operator[](std::size_t x, std::size_t y) { return data[y * N + x]; }
  const T& operator[](std::size_t x, std::size_t y) const { return data[y * N + x]; }
  
  auto getMemory() -> std::span<const T> const {
    return std::span<const T>(data);
  }
};

int main(){
    mat_t<float, 2> mat;

    std::println("{}", mat.getMemory());
}
versed harbor
#

yeah....

twin dawn
#

std span is pretty good for graphics

#

because it has a size_bytes() member function

#

and you can always add type aliases:

using mat2 = mat_t<float, 2>;
using mat3 = mat_t<float, 3>;
using mat4 = mat_t<float, 4>;
versed harbor
#

^ if thats what I have to do then i dont see myself enjoying programming.

twin dawn
#

this is what glm does, they have a generic mat_t and they alias all the different template specializations

versed harbor
#

I really appreciate the help, but thats not up my ally

twin dawn
#

and sometimes being the guy who writes the complicated shit that needs to be abstracted

versed harbor
#

if thats less complicated than I dont have a barometer for "complicated"

twin dawn
weak elbow
twin dawn
versed harbor
#

I was just trying to move some bits around and make something readable that would produce sane error messages

#

I honestly think you just sold me on picking a C standard and rolling my own containers.

weak elbow
twin dawn
#

of course you sometimes need to account for stride and whatnot

#

but that is pretty easy to get with the offsetof (operator? expression? idk)

weak elbow
#

and in that regard, c isn't very "ergonomic" when it comes to your ability to build your own abstractions

twin dawn
weak elbow
#

though if you're adamant in thinking in terms of raw data more than in terms of abstraction then I guess c can be a better fit for you

twin dawn
#

you just treat it as a black box that does its job

versed harbor
#

I would ask though. About the above unions being UB, where could I look at some discussion on that? any specific term I could look for?

twin dawn
#

then abstract it so it is sane to use

twin dawn
#

the active member is the last member that was "assigned to" (there is a complicated wording for it which i dont remember)

weak elbow
#

C doesn't quite have that rule about active/inactive union members

versed harbor
#

oh that makes sense. assigning raw[0] and reading x could be considered "UB"

twin dawn
weak elbow
#

and the C standard has a note basically saying that doing that read does what c++ calls a bit_cast or some such

versed harbor
#

yeah english is not my first language

twin dawn
#

neither is it mine bing_shrug

weak elbow
#

probably phrased as a memcpy but I can't remember that, I don't dwadle through the c standard as much as I do the c++ standard

versed harbor
#

alright im cool here

weak elbow
#

I periodically have "english moments" where I can't english anymore

versed harbor
#

I dont like the way the convo is going. I really thank you both for your help

twin dawn
versed harbor
#

I understand the answer now

#

!solved

desert vaporBOT
#

Thank you and let us know if you have any more questions!

This thread is now set to auto-hide after an hour of inactivity

weak elbow
#

and I wouldn't call it that but it does depend where you draw the line