Skip to main content
13 events
when toggle format what by license comment
Aug 14, 2022 at 2:18 comment added doug I did some testing and it turns out list.begin() == list.end()) is never true when the constructor is called. x{} calls the default ctor and x{{}} calls the the constructor with list.size()==1 and the contained list has size 0. Improved it and posted the improvement as an answer. Also used a tag in the raw ctor to make it inaccessible to users. Code not shown. Not sure if I should just update the main post.
Aug 12, 2022 at 14:50 comment added doug @MartinYork Agree about needed comments. S/B at the top of the class along with a description of general requirements for handling const subobjects. I've been trying to find the cleanest way to deal with users writing Matrix2D<T> x{}; because initializer_list is greedy. Got one but it's uglier than I like. Normally use std::vector but this has 40% less object size.
Aug 11, 2022 at 21:47 history edited Loki Astari CC BY-SA 4.0
added 88 characters in body
Aug 11, 2022 at 21:43 comment added Loki Astari @doug I understand what you are trying to do. But my main goal is preventing bugs (not just now long term). For that you have to think what will happen in the future. To make your class resistant to bugs future bugs, you simply need to call std::destroy_at() before a call to std::construct_at() and now it will be safe to use now and in all situations in the future. Alternatively, you need to stack a large set of READ-ME comments somewhere to make sure future maintainers are aware of potential issues.
Aug 11, 2022 at 21:22 comment added doug @MartinYork The class is designed to be as small as possible but sure if someone added something like a vector or string to it things get quite complicated. The main one is that you can't make them const w/o disabling the move ops in addition to specifically destroy them as well. Major pessimization. But this is a small, simple object highly useful for matrix ops.
Aug 11, 2022 at 20:48 comment added doug @MartinYork Ah. Good catch. s/b cols(list.size()==0 ? 0 : (list.begin())->size()),
Aug 11, 2022 at 19:36 comment added Loki Astari @doug (list.begin())->size() is UB if list.begin() == list.end()).
Aug 11, 2022 at 19:35 comment added Loki Astari @doug An object's lifetime can be ended by replacing it's contents as long as there are no other side effects that explicit call to a destructor. Assuming that is true. Then, that's great for this version; but you are not considering maintainability of the code. It makes the assumption that no member will ever be added that is non trivial. BUT this class has a destructor with a side effect.
Aug 11, 2022 at 18:36 comment added doug @MartinYork Why would size() not be valid? It's 0 when empty and that's valid in the new The reason I put in if (rows > 0 && cols > 0) was to prevent false positives which show up in MSVC's intelliense. And it only sometimes works. Had a similar (non) problem with some of the stl one-liners.
Aug 11, 2022 at 18:24 comment added doug @MartinYork An object's lifetime can be ended by replacing it's contents as long as there are no other side effects that explicit call to a destructor would produce. See basic.life Hence std::destroy_at is not required.
Aug 11, 2022 at 17:06 comment added Loki Astari @G.Sliepen I missed the const part of the issue. But the main problem is that the object is alive. So it will be destroyed first: std::destroy_at() to make sure the lifetime ends then you can restart the lifetime with std::construct_at()
Aug 11, 2022 at 16:52 comment added G. Sliepen I had the same reservations about std::construct_at(), but it seems it is allowed, as long as you make sure everything ends up in a valid state? See [chat.stackexchange.com/rooms/137845/… chat I had with doug).
Aug 11, 2022 at 16:37 history answered Loki Astari CC BY-SA 4.0