Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Absurd Alhazred
Mar 27, 2010

by Athanatos

giogadi posted:

I seem to recall some random trivia that, if you want to represent a 3D Vector as a struct, it can be advantageous to actually store 4 values:

code:
struct Vector3d {
    float x, y, z, unused;
};
Has anyone else heard this? My only guess here is that this helps guarantee that your vectors will fit neatly in a 32B cache line (because a 12-byte vector would not evenly divide 32B). This means that each vector access would require only 1 cache read. But there's a tradeoff here, right? It seems like you can't store as many vectors in the cache if each one is bigger.

What do y'all think?

Well, depending on the compiler, it might be able to automagically compile a lot of vector code into SSE intrinsics. If you use a library dedicated to 3d-graphics-adjacent vector math, like GLM, you can enforce this through template parameters, even.

Adbot
ADBOT LOVES YOU

more falafel please
Feb 26, 2005

forums poster

Absurd Alhazred posted:

Well, depending on the compiler, it might be able to automagically compile a lot of vector code into SSE intrinsics. If you use a library dedicated to 3d-graphics-adjacent vector math, like GLM, you can enforce this through template parameters, even.

Yeah, it's for vector intrinsics, which usually need their arguments to be aligned on 4-word/16-byte boundaries.

giogadi
Oct 27, 2009

Absurd Alhazred posted:

Well, depending on the compiler, it might be able to automagically compile a lot of vector code into SSE intrinsics. If you use a library dedicated to 3d-graphics-adjacent vector math, like GLM, you can enforce this through template parameters, even.

more falafel please posted:

Yeah, it's for vector intrinsics, which usually need their arguments to be aligned on 4-word/16-byte boundaries.

Thanks! I'm trying to experiment to make sure I understand the concept correctly. It turns out that just putting 4 values in the struct does not guarantee 16-byte alignment of the struct. Here's an example that shows this:

code:
#include <iostream>

struct Foo {
    float w,x,y,z;
};

int main() {
    char x;
    Foo f;
    std::cout << &f << std::endl;
}
The output on my machine is "0x7ffee84cf8c8", which is not 16-byte aligned. Does this mean that the compiler will never vectorize my code unless I explicitly add "alignas(16)" to the Foo declaration, or is that something the compiler could also handle on its own?

more falafel please
Feb 26, 2005

forums poster

That would do it, so would
code:
#pragma pack(push, 16)
.
.
.
#pragma pack(pop)

Jeffrey of YOSPOS
Dec 22, 2005

GET LOSE, YOU CAN'T COMPARE WITH MY POWERS

giogadi posted:

I’m not sure - I always thought the fastest way to rotate a 3d vector is just to multiply with a 3x3 rotation matrix. Like, you can directly rotate a vector with a quaternion but it’s about as fast as converting the quat into a rotation matrix and just rotating that way. But I might be wrong!
Rotation works fine with 3D, but if you want to also do translation as part of your transformation, you want an extra dimension so you can do it in a single matrix multiply, instead of a matrix multiply and a vector addition. This lets you easily use the same transformation matrix for points, which get translated, and vectors, which are just length and direction and don't have any fixed position to translate - when you extend a point or vector to 4 dimensions, the vector would leave the 4th dimension value as 0, while a point would set it to 1 to include the translation component.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
I was just cleaning up old environments at work, and I found a comical thing I wrote to make constexpr maps in C++, keyed on strings or ints.

The idea being you can do something like

code:
constexpr auto kSomething = ImmutableMap<const char*, const char*>()
  .add("fish", "good")
  .add("banana", "bad");
And it compile-time constructs a sorted array of key-value pairs with binary search capability, so there's no init-time cost to creating your lookup tables like there would be with a const std::map or similar.

But the reason it's still floating in an old environment is it had an annoying issue where g++ (or maybe it was clang) complained about accessing arrays out of bounds, because it had a bit in it like

code:
  something = TemplatedIntValue < OtherTemplatedIntValue ? v[YetAnotherTemplatedIntValue-1] : v[YetAnotherTemplatedIntValue+1];
So it was analyzing the code and going "oh no, there's a v[x+1] when x is the position of the last element, OUT OF BOUNDS!!!" (and the same for -1 when x is 0), but the reality is it wouldn't ever actually take that path, and it should know that because it's a constexpr thing, it's all done at compile time, it shouldn't be analyzing code that doesn't exist.

I could make it work with a #pragma disabling that warning before the template code and re-enabling it after, but unfortunately that kind of #pragma doesn't support push/pop behavior, so that would mean my template code could unintentionally enable a warning that the user did not want for any files included after that one. So my amazing convoluted class of nonsense never saw the light of day.

Xerophyte
Mar 17, 2008

This space intentionally left blank
Re: coordinate transforms, there are a couple of different options, with different trade-offs in how hard it is to apply them to a vector, how much memory footprint they require and how hard it is to compose two different transforms to arrive at the "first A, then B" transform. If you're in a situation where the representation matters -- which you generally are not -- then you might use one representation for storage, one when applying or compositing, you might support multiple representation types for different scenarios and batch process each type separately, etc.

A list:
- 3x3 matrices can represent some combination of rotation, scale and shear. Compose easily. 9 floats storage, 15 flops to apply (ignoring vectorization, fma, real hardware in general), 45 flops to compose.
- A 3x3 matrix + offset vector represents any affine transform (i.e. also translates) and composes about as well. 12 floats storage, 18 flops to apply, 48[E:] 60ish flops to compose.
- 4x4 matrices also do any affine transform through homogeneous coordinates, likewise compose well. 16 floats storage (naively), 28 flops to apply, ... I'unno, 80ish flops to compose naively I think.
- Axis of rotation + angle represents rotation only. Cheap to store at 3 or 4 floats, 32 flops and some trig to apply. Basically can't be composed without switching to another representation.
- Euler angles are rotation only. Cheap to store at 3 floats, easy to apply if trig is cheap. Has degenerate gimbal lock issues, hard to compose.
- Quaternions are effectively rotation only (you have the freedom to do other things, but I'm sure as hell not going to). 4 floats worth of storage, I think something like 20 flops both to apply and to compose.

The flops numbers are highly dubious in terms of real cycles since hardware instructions for basic float vector operations have been around on mainstream CPUs for over 20 years and vectorizing linear algebra is just about all a GPU does. Any sane library will use the hardware vector implementation for matrix and quaternion operations. A nice compiler might figure it out too if your float math is really straightforward, but generally don't expect it.

No one does Euler angles, they suck. Sorry Leonhard. Axis-angle happens for storage if you really need the space/cache efficiency, but is usually converted to some other representation for actual use. 4x4 matrix is the go-to when you actually have a homogeneous coordinate and want a full affine transform. 3x3 matrix is generally better than 4x4 for the transforms it supports: typically as fast in hardware, faster to compose and you fit more transforms in cache. 3x3 matrix + offset vector is mainly a thing in cases where you need the translation component in higher precision (not uncommon in CAD). Quaternions are the go-to option for pure rotations because they have a small cache footprint, compose very easily and are reasonably fast to apply. Only drawback is that they can't realistically do anything but rotations.

tl;dr: just use 4x4 matrices and homogeneous coordinates everywhere unless you really care about the storage footprint of your millions of transforms or are doing a bunch of rotational composition that absolutely must be blazing fast. If you do have to care, use a good vectorized library (e.g. Eigen) and profile because it's hard to guess at the real-world performance. It depends on the balance of composition-vs-application, if you're applying one transform to many vectors or applying several different transforms, how cache-friendly your data layout is, etc. Whatever library you use will probably handle 3x3 and 4x4 matrix multiplies with the same __m128 types and intrinsics, but you want avoid caring about that particular detail unless your interest is specifically teaching yourself vectorization.

Xerophyte fucked around with this message at 14:51 on Mar 10, 2021

more falafel please
Feb 26, 2005

forums poster

UE3 used Euler angles all over the place, it was a mess.

Xerophyte
Mar 17, 2008

This space intentionally left blank

more falafel please posted:

UE3 used Euler angles all over the place, it was a mess.

I mean, they make sense as a user-facing input. Just don't do vector math with them.

more falafel please
Feb 26, 2005

forums poster

Xerophyte posted:

I mean, they make sense as a user-facing input. Just don't do vector math with them.

Yeah, but they did. It's a miracle any game ever shipped on UE3, let alone that a lot of them were good.

Beef
Jul 26, 2004

chglcu posted:

FTFY

After using it for game development for over 20 years, I've recently taken a hard hard turn into being sick of its bullshit. Just sucks that the alternatives seem to be even worse for that particular niche.

I know what you mean. Rust is a bit too opinionated. Nim and especially D are for me the more appealing ones, especially the latter one. D is literally a "sick of C++'s bullshit" the language, created by gamedev and C++ compiler writer Walter bright. It has seen some use in gamedev at Remedy for rapid prototyping through dynamic linking iDTech style, but doesn't seem to get much more traction.

baby puzzle
Jun 3, 2011

I'll Sequence your Storm.
I miss the in-house math libraries we used at avalanche that used geometric algebra. So, rotors instead of quats. And frankly I don’t even understand the math enough to have a valid preference.

Insurrectum
Nov 1, 2005

Xerophyte posted:

Re: coordinate transforms, there are a couple of different options, with different trade-offs in how hard it is to apply them to a vector, how much memory footprint they require and how hard it is to compose two different transforms to arrive at the "first A, then B" transform. If you're in a situation where the representation matters -- which you generally are not -- then you might use one representation for storage, one when applying or compositing, you might support multiple representation types for different scenarios and batch process each type separately, etc.

A list:
- 3x3 matrices can represent some combination of rotation, scale and shear. Compose easily. 9 floats storage, 15 flops to apply (ignoring vectorization, fma, real hardware in general), 45 flops to compose.
- A 3x3 matrix + offset vector represents any affine transform (i.e. also translates) and composes about as well. 12 floats storage, 18 flops to apply, 48[E:] 60ish flops to compose.
- 4x4 matrices also do any affine transform through homogeneous coordinates, likewise compose well. 16 floats storage (naively), 28 flops to apply, ... I'unno, 80ish flops to compose naively I think.
- Axis of rotation + angle represents rotation only. Cheap to store at 3 or 4 floats, 32 flops and some trig to apply. Basically can't be composed without switching to another representation.
- Euler angles are rotation only. Cheap to store at 3 floats, easy to apply if trig is cheap. Has degenerate gimbal lock issues, hard to compose.
- Quaternions are effectively rotation only (you have the freedom to do other things, but I'm sure as hell not going to). 4 floats worth of storage, I think something like 20 flops both to apply and to compose.

The flops numbers are highly dubious in terms of real cycles since hardware instructions for basic float vector operations have been around on mainstream CPUs for over 20 years and vectorizing linear algebra is just about all a GPU does. Any sane library will use the hardware vector implementation for matrix and quaternion operations. A nice compiler might figure it out too if your float math is really straightforward, but generally don't expect it.

No one does Euler angles, they suck. Sorry Leonhard. Axis-angle happens for storage if you really need the space/cache efficiency, but is usually converted to some other representation for actual use. 4x4 matrix is the go-to when you actually have a homogeneous coordinate and want a full affine transform. 3x3 matrix is generally better than 4x4 for the transforms it supports: typically as fast in hardware, faster to compose and you fit more transforms in cache. 3x3 matrix + offset vector is mainly a thing in cases where you need the translation component in higher precision (not uncommon in CAD). Quaternions are the go-to option for pure rotations because they have a small cache footprint, compose very easily and are reasonably fast to apply. Only drawback is that they can't realistically do anything but rotations.

tl;dr: just use 4x4 matrices and homogeneous coordinates everywhere unless you really care about the storage footprint of your millions of transforms or are doing a bunch of rotational composition that absolutely must be blazing fast. If you do have to care, use a good vectorized library (e.g. Eigen) and profile because it's hard to guess at the real-world performance. It depends on the balance of composition-vs-application, if you're applying one transform to many vectors or applying several different transforms, how cache-friendly your data layout is, etc. Whatever library you use will probably handle 3x3 and 4x4 matrix multiplies with the same __m128 types and intrinsics, but you want avoid caring about that particular detail unless your interest is specifically teaching yourself vectorization.

Just wanted to say that this is a great post.

giogadi
Oct 27, 2009

Yeah, that was super helpful. Much appreciated!

Xerophyte
Mar 17, 2008

This space intentionally left blank

baby puzzle posted:

I miss the in-house math libraries we used at avalanche that used geometric algebra. So, rotors instead of quats. And frankly I don’t even understand the math enough to have a valid preference.

Cool! About my sum total knowledge about geometric algebra is that quaternions are equivalent to some of it (googling says they're equivalent to the subalgebra G(3,0), whatever that means) and that you can use them to "extend" quaternions to all conformal (rotation, translation, mirroring) transforms in some nice way that I don't understand. Not that I really understand quaternions either, I can just encode a rotation in them.

I've never come across anyone using GA, or any code that does; I didn't know Avalanche did. What did you like about it? Did it handle non-conformal transforms?

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
Geometric algebra is nice because it's a bit more intuitive to derive and generalizes better to other dimensionalities. It doesn't actually make much difference in your code, or any difference in your performance, at the end of the day, but it would still be cool to see it used more.

more falafel please
Feb 26, 2005

forums poster

No one "understands" quaternions, but don't let that stop you from using them.

Nalin
Sep 29, 2007

Hair Elf
code:
struct A2
{
    int x;
    int y;
    int data[2];
};

struct A3
{
    int x;
    int y;
    int z;
    int data[3];
};

template <typename T>
concept isA3 =
requires (T& t) {
    { t.x };
    { t.y };
    { t.z };
};

template <typename T> requires isA2<T>
void doStuff(const T& t);

template <typename T> requires isA3<T>
void doStuff(const T& t);

How can I make an isA2 concept that wouldn't make the doStuff function ambiguous for A3? Because no matter how much I search on stuff like SFINAE and whatnot, nobody ever seems to have ever had the question, "How do I check for something NOT existing?"

Nalin fucked around with this message at 02:58 on Mar 12, 2021

Nalin
Sep 29, 2007

Hair Elf

Nalin posted:

How can I make an isA2 concept that wouldn't make the doStuff function ambiguous for A3? Because no matter how much I search on stuff like SFINAE and whatnot, nobody ever seems to have ever had the question, "How do I check for something NOT existing?"

Took me forever but I was finally able to solve it.

code:
template<typename T>
concept isA3 =
requires (T& t)
{
    { t.x };
    { t.y };
    { t.z };
};

template<typename T>
concept pack_2 = (sizeof T::data / sizeof(std::remove_all_extents_t<decltype(T::x)>)) == 2;

template<typename T>
concept isA2 =
requires (T& t)
{
    { t.x };
    { t.y };
    requires pack_2<T>;
};

ultrafilter
Aug 23, 2007

It's okay if you have any questions.


Just out of curiosity, why do you need to know than an A2 is not an A3?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Because otherwise calling doStuff on an A3 is ambiguous - the value matches both the A2 and A3 concepts, so it's not clear which one should be used.

The idea is to make the A2 declaration uninstantiable for things that are actually an A3, the same way the A3 declaration is inherently uninstantiable for things that are "just" an A2 without any z value.

What I don't totally understand (perhaps because something is lost in converting the real situation to a toy example) is why the situation even uses templates and concepts to begin with.

Nalin
Sep 29, 2007

Hair Elf

Jabor posted:

What I don't totally understand (perhaps because something is lost in converting the real situation to a toy example) is why the situation even uses templates and concepts to begin with.

Basically, I am using Google mathfu, which does terrible things like this:

code:
template <typename T>
class vector<T, 2>
{
    union {
        T data[2];
        struct {
            T x;
            T y;
        };
    };
};
I wanted to make a generic conversion function that could convert a vector<int, 2> to a vector<float, 2>, and any other data type. I also wanted it to work on vector<T, 3> with the same name, but overloaded.

Google was very nice in providing a vector::FromType/ToType function which helpfully just memcpy's the whole data[] array, because that's a great way to frustrate people trying to debug why everything has exploded. Turns out you can't memcpy a float into an int and make it work.

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

Nalin posted:

I wanted to make a generic conversion function that could convert a vector<int, 2> to a vector<float, 2>, and any other data type. I also wanted it to work on vector<T, 3> with the same name, but overloaded.

Surely you should just be using the array representation, no?

code:
template<typename TO, typename FROM, size_t SIZE>
vector<TO, SIZE> convert(const vector<FROM, SIZE> &x) {
  vector<TO, SIZE> y;
  for(size_t i = 0; i < SIZE; ++i)
    y.data[i] = x.data[i];
  return y;
}
I mean, I'm assuming that these things are packed appropriately for this to work correctly, but working with the integer-indexed data seems a lot simpler than trying to deal with overloads and named members.

Nalin
Sep 29, 2007

Hair Elf

ShoulderDaemon posted:

I mean, I'm assuming that these things are packed appropriately for this to work correctly, but working with the integer-indexed data seems a lot simpler than trying to deal with overloads and named members.

It's at this point where "typedef mathfu::Vector<float, 2> Vector2df;" enters the whole codebase and screws up everything.

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

Nalin posted:

It's at this point where "typedef mathfu::Vector<float, 2> Vector2df;" enters the whole codebase and screws up everything.

I think I must not be understanding the problem you're encountering, because it works okay for me.

Nalin
Sep 29, 2007

Hair Elf

ShoulderDaemon posted:

I think I must not be understanding the problem you're encountering, because it works okay for me.

You know, you are probably right. I could have sworn I tried it and got an error. Wouldn't it just be my luck to have mistaken the problem and spent way too much time messing around with stupid stuff.

Xarn
Jun 26, 2015
That pretty much summarizes programming

Lime
Jul 20, 2004

Nalin posted:

How can I make an isA2 concept that wouldn't make the doStuff function ambiguous for A3? Because no matter how much I search on stuff like SFINAE and whatnot, nobody ever seems to have ever had the question, "How do I check for something NOT existing?"

So your real question has already been answered but if for some reason in the future you really do need to check for a field not existing, you could do it like: (godbolt link)

code:
struct A2 { int x; int y; };
struct A3 { int x; int y; int z; };

template <typename X, typename = void> constexpr bool has_z = false;
template <typename X> constexpr bool has_z<X, std::void_t<decltype(X::z)>> = true;

template <typename T> concept isA2 = requires (T& t) { t.x, t.y; } && !has_z<T>;
template <typename T> concept isA3 = requires (T& t) { t.x, t.y, t.z; };

template <typename T> requires isA2<T> void doStuff(const T &t) { std::cout << "do(A2)\n"; }
template <typename T> requires isA3<T> void doStuff(const T &t) { std::cout << "do(A3)\n"; }

int main() {
    doStuff(A2{1,2});
    doStuff(A3{1,2,3});
}

Nalin
Sep 29, 2007

Hair Elf

Nalin posted:

You know, you are probably right. I could have sworn I tried it and got an error. Wouldn't it just be my luck to have mistaken the problem and spent way too much time messing around with stupid stuff.

It's the next day and I'm refreshed now. I know why I didn't see that method of doing it. I was completely focused on doing:
auto vec = convert<Vector2di>(floatvec);

It is definitely a lot more simple to do:
auto vec = convert<int32_t>(floatvec);

Lime posted:

So your real question has already been answered but if for some reason in the future you really do need to check for a field not existing, you could do it like: (godbolt link)

Awesome, thanks! I eventually figured out a similar thing for a different problem I was having. Well, if anything, flailing around like this is definitely giving me a better understanding of things like SFINAE and concepts.

Beefeater1980
Sep 12, 2008

My God, it's full of Horatios!






I’ve been hugely enjoying ploughing through CS50, but having finally gone back with the benefit of a couple of extra weeks’ knowledge and compiled a version of Tideman that worked for all tests I have to say: gently caress that guy and his horrible election ranking system.

E: it’s not really a question I just wanted to vent because good God that was an exercise in patience.

FastEddie
Oct 4, 2003

The downside to adding items to the end of a vector is that the internal array may be resized when its capacity is reached. This can be a somewhat expensive operation if your vector already has a lot of items in it.

If you know in advance the number of items you'll be push_backing into your vector, you can make sure there's enough space in the internal array for them by calling the vector's "reserve" member function beforehand.

e: This is an answer to a question that I now cannot find in the thread. :confused:

FastEddie fucked around with this message at 10:59 on Mar 15, 2021

Xarn
Jun 26, 2015
Just keep in mind that keeping reserve more than twice on one instance of vector is likely serious performance bug. :v:

cheetah7071
Oct 20, 2010

honk honk
College Slice
This is a bit of a longshot, but does anybody here have any experience with any of the C++ libraries designed to read lidar data? (i.e., laz files). None of the ones with documented APIs seem to support laz format 1.4, which I need. Laszip (which backs all the libraries) supports 1.4 but has extremely poor documentation and sometimes it just seems to return 0 instead of the actual values present in the file (which I can verify using the well-documented libraries in other languages). It's probably my own drat fault with not understanding the poorly-document API though.

e: lmao it was extremely dumb and had nothing to do with misunderstanding the api

the documentation was so poor that I was having trouble to get my code to even compile, and ended up linking to both the current and old-version .lib file. When I cleaned out my links to only link to the current version it worked fine.

cheetah7071 fucked around with this message at 00:03 on Mar 16, 2021

Sweeper
Nov 29, 2007
The Joe Buck of Posting
Dinosaur Gum
Hello C++ thread, we are hiring people to work on trading/execution platforms in NYC. Most of our code is C++, we have a bunch of transport layer stuff in C, and you should be familiar enough with C to read our tactic code. We are also looking to use Rust for future systems, so if you know and/or want to know Rust that is a plus. A large number of our tests (especially integration tests, we test multiple trading systems at once) are coordinated in typed python3, so familiarity with python and type annotations is a big plus. You will be expected to get your Series 57 (https://www.finra.org/registration-exams-ce/qualification-exams/series57), requires recertification every few years in the form a CYOA. Position is not fully remote, after the pandemic cools you can do a couple days a week from home. Shoot me a PM if you are interested and I can give you some more details.

csammis
Aug 26, 2003

Mental Institution

Sweeper posted:

You will be expected to get your Series 57 (https://www.finra.org/registration-exams-ce/qualification-exams/series57), requires recertification every few years in the form a CYOA

lol at the idea that financial “regulations” in this country are administered by Choose Your Own Adventure


quote:

You are about to change code governing single transactions if more money than most human beings will ever earn in a lifetime. Suddenly, you notice a flaw in the logic...

After thinking about it for the seventy third work hour of the week you realize it can be leveraged to give you sole access to trade information one millisecond sooner than your bosses!

>> To do a crime which is somehow still legal, turn to page 112

>> To do a different legal crime, turn to page 86

Sweeper
Nov 29, 2007
The Joe Buck of Posting
Dinosaur Gum

csammis posted:

lol at the idea that financial “regulations” in this country are administered by Choose Your Own Adventure

Well the initial test is a lovely test you go to a testing center to take. If I recall it’s a couple hours of multiple choice questions about the financial industry, regulations, basics of the the different securities and how they work, why they exist, etc. the test just makes sure you have any idea how finance works, you need to know the regulations exist to be able to look them up and follow them (compliance department is obviously the backstop on did you follow it)

Beef
Jul 26, 2004
I'de rather do a CYOA than the mandatory silverlight-powered stock footage masterpieces of :
"You meet up with your friend Nancy working for a competitor. In a private meeting she asks you to fix prices. Do you a) agree b) tell her you agree but secretly do not do it or c) notify your manager, legal, and the fraud and compliance officer"
Yes, now I'm totally up to speed with ethics and compliance laws!


To post some actual C++ content:

With Concepts finally being in a released standard, are we seeing an uptick in the use of C++ template mixins? I remember them being pretty neat, but seen rarely. Likely it's because it just introduced yet another giant footgun. Concepts seem to solve some of its problems, on paper at least.

Xarn
Jun 26, 2015
You mean what some people call policy-based design, e.g. std::lock<mutex-type>, where mutex type changes what actually happens?

Nalin
Sep 29, 2007

Hair Elf

Beef posted:

With Concepts finally being in a released standard, are we seeing an uptick in the use of C++ template mixins?

I've never used mixins before, but at least in my hobby projects I've started to make use of concepts in general. I usually try to filter my template with a requires to reduce arcane compiler errors. Like, just a few days ago I took a template function that converts an enum to a number and threw a "requires std::integral<T>" on it. I've also taken to creating new concepts for templates that operate on class member variables and functions in order to make simpler error messages.

Adbot
ADBOT LOVES YOU

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Sweeper posted:

Well the initial test is a lovely test you go to a testing center to take. If I recall it’s a couple hours of multiple choice questions about the financial industry, regulations, basics of the the different securities and how they work, why they exist, etc. the test just makes sure you have any idea how finance works, you need to know the regulations exist to be able to look them up and follow them (compliance department is obviously the backstop on did you follow it)

The point of these "tests" is not to actually verify your knowledge; it is to let your employer document that yes, we totally trained Mr. Sweeper on safety/environmental/security regulations, here is confirmation that he passed the test, so this injury/oil spill/disclosure of customer information is totally his fault and not the company’s.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply