4 ms·
> I doubt it's really safer at that point. the number of bugs that the compiler has saved me by e.g. having a simple Id<T> type tag instead of ints as used by
by jcelerier 6y ago
> I doubt it's really safer at that point.
the number of bugs that the compiler has saved me by e.g. having a simple Id<T> type tag instead of ints as used by every C library under the sun is absurd.
- jstimpfle 6y agoI don't know, I've tried approaches like that, even played with writing a few C++ helper functions, and even started a compiler with the goal of exploring ideas like this. How do you go about Id<T>? The way I see that something like this can work out and give small advantages is that T would be an abstract type (a phantom or tag type, or whatever C++ guys are calling it). And all arrays that are meant to be indexed using Id<T> (while the array element types could be whatever) would depend on this type and have to be implemented using a special wrapped array type with overloaded operator[]. I don't know, this might come with many disadvantages. All the stuff goes out the roof when you're now dealing with start indices + slices, i.e. doing "pointer" arithmetics. My general feeling is that this Id<T> approach might show problems similar to the idea of using typed units, like wanting to prevent the expression "1W + 3s" but then making it terribly cumbersome to do real work, e.g. "1W * 3s" which would be perfectly valid. In one C project I resorted to using about 20-30 typedefs like: typedef int Expr; typedef int Symbol; etc. And I used these typedef names in function signatures. Variables also were named like expr, parentExpr, symbol, etc. It worked wonderfully. I had maybe 1 mistake where I submitted the wrong "type" in 6 months. And I'm someone who makes a lot of stupid mistakes.
- jcelerier 6y ago> How do you go about Id<T>? The way I see that something like this can work out and give small advantages is that T would be an abstract type (a phantom or tag type, or whatever C++ guys are calling it). in a very simplified way: template<typename T> struct Id { int value; }; template<typename T> struct Identifiable { Id<T> id; }; struct MyEntity : Identifiable<MyEntity> { string name; void foobar(); }; > And all arrays that are meant to be indexed using Id<T> (while the array element types could be whatever) would depend on this type and have to be implemented using a special wrapped array type with overloaded operator[]. std::unordered_map<Id<T>, whatever> works fine (or your container of choice... flat_map, boost::multi_index...). > It worked wonderfully. I had maybe 1 mistake where I submitted the wrong "type" in 6 months. well, you're good, I remember when I introduced this in my code base, that caught a dozen bugs almost immediately - and I get prevented by the compiler to introduce more every couple months.