{"id":18933504,"url":"https://github.com/positiveblue/user-defined-types-cpp","last_synced_at":"2026-03-19T09:30:16.567Z","repository":{"id":70775808,"uuid":"90536022","full_name":"positiveblue/User-Defined-Types-Cpp","owner":"positiveblue","description":"User-Define Types in C++","archived":false,"fork":false,"pushed_at":"2017-05-09T09:13:34.000Z","size":7,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-31T20:43:05.475Z","etag":null,"topics":["compilers","cpp","cpp11","cpp14","cpp17","modern-cpp"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/positiveblue.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-07T13:52:17.000Z","updated_at":"2017-05-09T09:03:04.000Z","dependencies_parsed_at":null,"dependency_job_id":"9bdd7f95-43e6-47a3-866f-76b3269c3e0f","html_url":"https://github.com/positiveblue/User-Defined-Types-Cpp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/positiveblue%2FUser-Defined-Types-Cpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/positiveblue%2FUser-Defined-Types-Cpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/positiveblue%2FUser-Defined-Types-Cpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/positiveblue%2FUser-Defined-Types-Cpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/positiveblue","download_url":"https://codeload.github.com/positiveblue/User-Defined-Types-Cpp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239933067,"owners_count":19720728,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compilers","cpp","cpp11","cpp14","cpp17","modern-cpp"],"created_at":"2024-11-08T11:54:57.308Z","updated_at":"2026-03-19T09:30:16.532Z","avatar_url":"https://github.com/positiveblue.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\nExtracted from [The C++ Type System Is Your Friend - Hubert Matthews ](https://www.youtube.com/watch?v=MCiVdu7gScs)\n\nThe **type system** in *C++* is very powerful and I have not seen many people using it. Using (correctly) the features of *C++* can help us to **write better, safer and faster code**.\n\nLet's go to say that we want to implement libMoment, a *C++* library for parsing, validating, manipulating, and formatting dates inspired in [Moment.js](http://momentjs.com/).\n\nA library for manipulating dates is a perfect example to show all the benefits of the **User-Defined Types (UDT)**. Many people would use C and C++ primitives to write a library like that (ints, floats, etc). However many errors can be derived if you uses primitives. The compiler would not be able to complain if you write something like this:\n\n```cpp\nauto year = 2017; // Actual year\n\n// Add 10 years to the year variable\nauto ten_years_ahead = year + 10; // Welcome to the future\n\n// It does not make any sense to add to years!!\nauto another_year = year + ten_years_ahead;\n```\n\nIt is well known that it is better to catch as many bugs at **compile time** as possible and the *type system* can help us with it. \n\nThe *type system* helps us to reason about our code in a more natural way. Given the constructor: \n\n```cpp\nDate(int, int, int);\n```\n\nwe have no idea (without reading the documentation or the code comments) how that function has to be used. Does Date receive the parameters as `Date(Year, Month, Day)`? Is it using the European format `Date(Day, Month, Year)` or the American one `Date(Month, Day, Year)`? A type alias can help with the expressivity but not the correctness:\n\n```cpp\nusing Year = int;\nusing Month = int;\nusing Day = int;\n\nDate(Month, Day, Year);\n```\n\nWhat we want is the compiler checking the types of each parameter, we want something like this:\n\n```cpp\nDay d(15);\nMonth m(1);\nYear y(2017);\n\nDate(m, d, y); // Compiles without any problem\nDate(d, m, y); // Error, type of d should be Month and type of m should be Day\n```\nwe do not want to compromise our performance or do it as little as possible, so we are looking for a zero-cost overhead solution.\n\n\n## User-Define Types in C++\n\nWe are going to use a pattern called *\"Whole value pattern\"*, it is just wrapping something up:\n\n```cpp\nclass Year {\npublic:\n explicit Year(int y) : _year{y} {}\n operator int const () { return _year; }\n\nprivate:\n int _year;\n}\n\nYear year = Year(2016)\n```\n\nTake care of the `explicit` keyword. We do not want integers becoming years if we do not specify it explicitly!\n\nIf you have many of these types in your code you can use the *C++* `operator\"\"` and make your code even more readable:\n\n```cpp\nYear operator\"\" _yr(unsigned long long v) { return Year(v) }\nYear y = 2016_yr;\n```\n\nWe do not want to copy and paste the same code again and again changing the name of the classes so we are going to generalize it using templates\n\n```cpp\nenum class UnitType { year_t, month_t, day_t }\n\ntemplate \u003cUnitType U\u003e\nclass Unit {\npublic:\n explicit Unit(int v) : _value{v} {}\n operator int const () { return _value; }\n\nprivate:\n int _value;\n}\n\nUsing Year = Unit\u003cUnitType::year_t\u003e;\nUsing Month = Unit\u003cUnitType::month_t\u003e;\nUsing Day = Unit\u003cUnitType::day_t\u003e;\n```\n\nNow you have a generic way to create your own types and make the compiler work for you!\n\n\n## Conclusion\nThis is a first approach to User-Defined Types in *C++*. This technique can have a huge impact on all those programs that use units. I am thinking basically about scientific programming, videogames engines, fintech, etc.. to name some of them. For those who are worried about the performance, all the code generated by te compiler is **exactly** the same (if you compile with -O2).\n\nYou can find many talks and posts about this topic but I recommend to start checking this combination:\n\n- Post from Fluent C++: [Strong types are (mostly) free in C++](http://www.fluentcpp.com/2017/05/05/news-strong-types-are-free/)\n- Post form Fluent C++: [Strong types for strong interfaces](http://www.fluentcpp.com/2016/12/08/strong-types-for-strong-interfaces/)\n- Video form ACCU: [The C++ Type System Is Your Friend - Hubert Matthews ](https://www.youtube.com/watch?v=MCiVdu7gScs) (this is a summary of the first 20 minutes of this talk)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpositiveblue%2Fuser-defined-types-cpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpositiveblue%2Fuser-defined-types-cpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpositiveblue%2Fuser-defined-types-cpp/lists"}