{"id":4755,"date":"2025-03-29T12:01:00","date_gmt":"2025-03-29T10:01:00","guid":{"rendered":"https:\/\/mariusbancila.ro\/blog\/?p=4755"},"modified":"2025-03-28T15:04:41","modified_gmt":"2025-03-28T13:04:41","slug":"whats-new-in-cpp26-contracts-part-3","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/","title":{"rendered":"What\u2019s new in C++26: contracts (part 3)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This article continues the series of posts about the new features included in C++26 (as they are accepted). This time I will focus on a single language feature: concepts. This has been under the radar of the standard committee for quite some time and it&#8217;s finally being added to the standard.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Contracts define language level assertions for checking preconditions, postconditions, and invariants for functions. Let&#8217;s see how they work (however, at the time of writing this article no major compiler has support for them).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Asserting before contracts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Asserting is possible with a macro called <code>assert<\/code>, available in the <code>&lt;cassert><\/code> header. Here is how we can use it to check some conditions:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename T>\nclass sequence\n{\npublic:\n    sequence(size_t capacity) : \n        capacity_(capacity), \n        size_(0)\n    {\n        data_ = new T[capacity_];\n    }\n\n    ~sequence()\n    {\n        delete[] data_;\n    }\n\n    T&amp; operator[](size_t index)\n    {\n        assert(index &lt; size_);\n        return data_[index];\n    }\n\n    const T&amp; operator[](size_t index) const\n    {\n        assert(index &lt; size_);\n        return data_[index];\n    }\n\n    size_t size() const\n    {\n        return size_;\n    }\n\n    void resize(size_t new_capacity)\n    {\n        assert(new_capacity > 0);\n        if(new_capacity &lt;= 0) return;\n\n        T* new_data = new T[new_capacity];\n        size_t min_size = std::min(size_, new_capacity);\n        for (size_t i = 0; i &lt; min_size; ++i)\n        {\n            new_data[i] = data_[i];\n        }\n\n        delete[] data_;\n        data_ = new_data;\n        capacity_ = new_capacity;\n        size_ = min_size;\n    }\n\n    void clear()\n    {\n        size_ = 0;\n    }\n\n    void push_back(const T&amp; value)\n    {\n        if(capacity_ == size_)\n            resize(capacity_ * 2);\n\n        data_[size_] = value;\n        size_++;\n    }\n\n    void pop_back()\n    {\n        if (size_ > 0)\n            size_--;\n    }\n\nprivate:\n    T*      data_;\n    size_t  size_;\n    size_t  capacity_;\n};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The check <code>assert(index &lt; size_)<\/code> in <code>operator[]<\/code> verifies that we don&#8217;t call with an index that is beyond the bounds of the sequence. Similarly, <code>assert(new_capacity > 0)<\/code> in <code>resize()<\/code> verifies we don&#8217;t resize to a zero capacity. However, just the assert is not enough, the program should ensure it does the right thing (such as throwing an exception) if the condition does not hold.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can turn off this checks by defining another macro called <code>NDEBUG<\/code> (keep in mind that although <code>assert<\/code> is a standard macro, <code>NDEBUG<\/code> is not).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These asserts are checked at runtime. But it&#8217;s also possible to define assertions at compile time with the use of <code>static_assert<\/code> (which is a keyword). Here is an example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename T>\nclass sequence\n{\n    static_assert(std::is_copy_constructible_v&lt;T>, \"T must be copyable\");\n};\n\nint main()\n{\n    sequence&lt;int> si(3);                      \/\/ OK\n    sequence&lt;std::unique_ptr&lt;int>> su(3);     \/\/ error: T must be copyable\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If we compile this code, we get a compiler error with the message &#8220;T must be copyable&#8221;, because <code>std::unique_ptr<\/code> is not copyable, and therefore cannot be used with our <code>sequence<\/code> class.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Enter contracts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">C++26 defines asserts as a language feature with the help of three new keywords:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>contract_assert<\/code>: is the equivalent of the <code>assert<\/code> macro, and is intended for performing checks at run-time. (As a side note, it could not be named <code>assert<\/code> because that would have conflicted with the <code>assert<\/code> macro.)<\/li><li><code>pre<\/code>: defines asserts for functions that specify preconditions<\/li><li><code>post<\/code>: defines asserts for functions that specify postconditions<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The argument for all these asserts is an expression that evaluates to a <code>bool<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>contract_assert<\/code> can be used in function bodies, while <code>pre<\/code> and <code>post<\/code> apply to function declarators. A function can have any number of <code>pre<\/code> and <code>post<\/code> asserts and they can be specified in any order. These two can be applied to:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>functions (both member and non-member)<\/li><li>function templates<\/li><li>lambda expressions<\/li><li>coroutines<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">On the other hand, <code>pre<\/code> and <code>post<\/code> cannot be applied to:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>functions that are defaulted (<code>=default<\/code>)<\/li><li>functions that are deleted (<code>=delete<\/code>)<\/li><li>virtual functions<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Here is how we can re-write the previous <code>operator[]<\/code> to use <code>contract_assert<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">T&amp; operator[](size_t index)\n{\n   contract_assert(index &lt; size_);\n   return data_[index];\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">However, for this particular case, the index being smaller than the size of the container is a precondition. Threfore, the best way to perform the assert is using the <code>pre<\/code> keyword:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">T&amp; operator[](size_t index)\n   pre (index &lt; size_)\n{\n   return data_[index];\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Similarly, we can define post asserts in the same manner:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void clear()\n   post (size_ == 0)\n{\n   size_ = 0;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">As previously mentioned, we can specify both pre- and post-conditions on the same function:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void resize(size_t new_capacity)\n   pre (new_capacity > 0)\n   post (size_ &lt;= capacity_)\n{\n   \/\/ ...\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In the case of the <code>post<\/code> assert, you can refer directly the object returned by the function, using the syntax shown below (notice that the name of the variable in the post assert can be anything that is a valid identifier):<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">sequence&lt;int> make_range(int const from, int const to)\n    pre (from &lt; to)\n    post(r: r.size() == to - from + 1))\n    post(r: r[0] == from)\n    post(r: r[r.size() - 1] == to)\n{\n    sequence&lt;int> s(to - from + 1);\n    for (int i = from; i &lt;= to; ++i)\n    {\n        s.push_back(i);\n    }\n    return s;\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Evaluation of asserts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Just like the <code>assert<\/code> macro can be undefined with another macro, so do contracts provide several possible evaluation semantics. These could be specified with a compiler flag. For instance, Clang and GCC provide one called <code>-fcontract-semantic<\/code>. The possible semantics are:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>ignore<\/code>: no check is performed<\/li><li><code>enforce<\/code>: the checks are performed and if one fails then a message is printed and the program terminates<\/li><li><code>observe<\/code>: the checks are performed and if one fails then a message is printed but the program continues its execution<\/li><li><code>quick-enforce<\/code>: the checks are performed and if one fails the program terminates immediately without printing a message and without doing anything else<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Note that whether termination happens with a call to <code>std::terminate<\/code> or <code>std::abort<\/code> is implementation defined.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Assertion violation handler<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When an assertion check fails a function called <code>handle_contract_violation<\/code> is called. This has the following signature:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void handle_contract_violation( std::contracts::contract_violation );<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A default implementation is provided but a user-defined replacement could be supplied. Note, however, that the standard does not guarantee this; it&#8217;s implementation-defined whether this handler can be replaced with a user-defined one or not.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Having a user-defined implementation is helpful in order to define your own strategy for handling the assertion failure. The <code>std::contracts::contract_violation<\/code> parameter of this function provides information about the failure (including location and evaluation semantic).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When the handler returns normally, the behavior of the program depends on the evaluation semantic:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>for <code>observe<\/code>, the program continues normally<\/li><li>for <code>enforce<\/code>, the program terminates<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Further readings<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To learn more about these topic see:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/isocpp.org\/files\/papers\/P2900R6.pdf\" target=\"_blank\" rel=\"noopener\" title=\"\">P2900R6: Contracts for C++<\/a><\/li><li><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/contracts\" target=\"_blank\" rel=\"noopener\" title=\"\">Contract assertions<\/a><\/li><li><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/functions\/function_contract_specifiers\" target=\"_blank\" rel=\"noopener\" title=\"\">Function contract specifiers<\/a><\/li><li><a href=\"https:\/\/timur.audio\/contracts_explained_in_5_mins\" target=\"_blank\" rel=\"noopener\" title=\"\">Contracts for C++ explained in 5 minutes<\/a><\/li><li><a href=\"https:\/\/www.youtube.com\/watch?v=8niXcszTjis\" target=\"_blank\" rel=\"noopener\" title=\"\">Cpp Contracts &#8211; How Contracts in C++26 Can Improve C++ Code Safety and Correctness<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This article continues the series of discussing the C++26 features with the topic of concepts, which are language level asserts for checking function preconditions, postconditions, and invariants.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[7],"tags":[451,647,648],"class_list":["post-4755","post","type-post","status-publish","format-standard","hentry","category-c","tag-c","tag-c26","tag-contracts"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\"c++,c++26,contracts\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"What\u2019s new in C++26: contracts (part 3)\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2025-03-29T10:01:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2025-03-28T13:04:41+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"What\u2019s new in C++26: contracts (part 3)\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2025\\\/03\\\/29\\\/whats-new-in-cpp26-contracts-part-3\\\/#article\",\"name\":\"What\\u2019s new in C++26: contracts (part 3)\",\"headline\":\"What\\u2019s new in C++26: contracts (part 3)\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"datePublished\":\"2025-03-29T12:01:00+02:00\",\"dateModified\":\"2025-03-28T15:04:41+02:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2025\\\/03\\\/29\\\/whats-new-in-cpp26-contracts-part-3\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2025\\\/03\\\/29\\\/whats-new-in-cpp26-contracts-part-3\\\/#webpage\"},\"articleSection\":\"C++, C++, C++26, contracts\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2025\\\/03\\\/29\\\/whats-new-in-cpp26-contracts-part-3\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"position\":4,\"name\":\"C++\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2025\\\/03\\\/29\\\/whats-new-in-cpp26-contracts-part-3\\\/#listItem\",\"name\":\"What\\u2019s new in C++26: contracts (part 3)\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2025\\\/03\\\/29\\\/whats-new-in-cpp26-contracts-part-3\\\/#listItem\",\"position\":5,\"name\":\"What\\u2019s new in C++26: contracts (part 3)\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2025\\\/03\\\/29\\\/whats-new-in-cpp26-contracts-part-3\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2025\\\/03\\\/29\\\/whats-new-in-cpp26-contracts-part-3\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2025\\\/03\\\/29\\\/whats-new-in-cpp26-contracts-part-3\\\/\",\"name\":\"What\\u2019s new in C++26: contracts (part 3)\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2025\\\/03\\\/29\\\/whats-new-in-cpp26-contracts-part-3\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2025-03-29T12:01:00+02:00\",\"dateModified\":\"2025-03-28T15:04:41+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"What\u2019s new in C++26: contracts (part 3)","description":"","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/","robots":"max-image-preview:large","keywords":"c++,c++26,contracts","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/#article","name":"What\u2019s new in C++26: contracts (part 3)","headline":"What\u2019s new in C++26: contracts (part 3)","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"datePublished":"2025-03-29T12:01:00+02:00","dateModified":"2025-03-28T15:04:41+02:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/#webpage"},"articleSection":"C++, C++, C++26, contracts"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","position":4,"name":"C++","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/#listItem","name":"What\u2019s new in C++26: contracts (part 3)"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/#listItem","position":5,"name":"What\u2019s new in C++26: contracts (part 3)","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/","name":"What\u2019s new in C++26: contracts (part 3)","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2025-03-29T12:01:00+02:00","dateModified":"2025-03-28T15:04:41+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"What\u2019s new in C++26: contracts (part 3)","og:url":"https:\/\/mariusbancila.ro\/blog\/2025\/03\/29\/whats-new-in-cpp26-contracts-part-3\/","article:published_time":"2025-03-29T10:01:00+00:00","article:modified_time":"2025-03-28T13:04:41+00:00","twitter:card":"summary","twitter:title":"What\u2019s new in C++26: contracts (part 3)"},"aioseo_meta_data":{"post_id":"4755","title":null,"description":null,"keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2025-03-28 09:57:57","updated":"2025-12-12 07:59:22","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":0,"uagb_excerpt":"This article continues the series of discussing the C++26 features with the topic of concepts, which are language level asserts for checking function preconditions, postconditions, and invariants.","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++26<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">contracts<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>","<span class=\"advgb-post-tax-term\">C++26<\/span>","<span class=\"advgb-post-tax-term\">contracts<\/span>"]}},"comment_count":"0","relative_dates":{"created":"Posted 2 years ago","modified":"Updated 2 years ago"},"absolute_dates":{"created":"Posted on March 29, 2025","modified":"Updated on March 28, 2025"},"absolute_dates_time":{"created":"Posted on March 29, 2025 12:01 pm","modified":"Updated on March 28, 2025 3:04 pm"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-1eH","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4755","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=4755"}],"version-history":[{"count":8,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4755\/revisions"}],"predecessor-version":[{"id":4763,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4755\/revisions\/4763"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=4755"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=4755"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=4755"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}