Intelligence Artificial

What Are The Differences Between Mutex And Shared Mutex In C++?

The concurrency support library in modern C++ is designed to solve read and write data securely in thread operations that allow us to develop faster multi-thread apps. This library includes built-in support for threads (std::thread), atomic operations (std::atomic), mutual exclusion (std::mutex), condition variables (std::condition_variable), and many other features. In C++14, in addition to mutex, there is a shared mutex (std::shared_mutex) which is an instance of the class located in header. In this post, we explain a frequently asked mutex question in modern C++, what are the differences between mutex and shared_mutex? What is a mutex (std::shared_mutex) in C++? Mutual Exclusion is a property of concurrency control and in programming, the Mutual Exclusion is a data exclusion method to lock and unlock data that provides exclusive access to a resource. This is mostly needed when we use shared data in multi-thread and multi-task operations in parallel programming. In C++, we can use std::mutex to define mutex data variables to protect his shared data from being simultaneously accessed by multiple threads. Here is an example of how we can use std::mutex with its lock() and unlock() methods,   std::mutex mtx;   mtx.lock();   // do operations mtx.unlock();   Here are more details and examples about std::mutex. What is a shared mutex (std::shared_mutex) in C++? The shared mutex comes with C++14, it is an instance of the class located in header and used with the shared_mutex class name in mutual exclusion operations of threads. The shared_mutex class is a part of the thread support library. It is a synchronization primitive for the thread operations that can be used to protect shared data when multiple threads try to access. Here is a simple example about std::shared_mutex with its try_lock_shared() and unlock_shared() methods that comes with C++17.   std::shared_mutex sharedmutex;   // in a thread function sharedmutex.try_lock_shared(); // do operations sharedmutex.unlock_shared();   Here are more details and a full example about shared_mutex. ———- LINK TO Learn About Useful Shared Mutexes Locking In Modern C++ —————— What are the differences between std::mutex and std::shared_mutex? While the std::mutex guarantees exclusive access to some kind of critical resource, the shared_mutex class extends this feature by a shared and exclusive level of accesses. The shared_mutex can be used in exclusive access level to prevent access of any other thread from acquiring the mutex, as in std::mutex. No matter if the other thread is trying to acquire shared or exclusive access. The shared_mutex can be used in the shared access level to allow multiple threads to acquire the mutex, but all of them are only in shared mode. In thread operations, exclusive access is not granted until all of the previously shared holders have returned the mutex. As long as an exclusive request is waiting, new shared ones are queued to be granted after the exclusive access. For more information about shared mutex feature, please see https://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3659.html C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs. There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, […]

Read More

What Is std::quoted Quoted String In Modern C++?

Sometimes we want to preserve the string format especially when we use string in a string with /”. In C++14 and above, there is a std::quoted template that allows handling strings safely where they may contain spaces and special characters and it keeps their formatting intact. In this post, we explain std::quoted quoted strings in modern C++. What Is Quoted String In Modern C++? The std::quoted template is included in  header, and it is used to handle strings (i.e. “Let’s learn from ”LearnCPlusPlus.org!” “) safely where they may contain spaces and special characters and it keeps their formatting intact.  Here is the syntax,   std::quoted( )   Here are C++14 templates defined in where the string is used as input,   template quoted( const CharT* s, CharT delim = CharT(‘”‘), CharT escape = CharT(‘\’) );   or   template quoted(   const std::basic_string& s,   CharT delim = CharT(‘”‘), CharT escape = CharT(‘\’) );   Here is a C++14 template defined in where the string is used as output,   template quoted( std::basic_string& s, CharT delim=CharT(‘”‘), CharT escape=CharT(‘\’) );   Note that this feature is is using std::basic_string and it improved in C++17 by the  std::basic_string_view support. What Is std::quoted quoted string in modern C++? Here is an example that uses input string and outputs into a stringstream:   const std::string str  = “I say “LearnCPlusPlus!””; std::stringstream sstr; sstr std::quoted(str_out);  // output sstr to str_out   Is there a full example about std::quoted quoted string in modern C++? Here is a full example about std::quoted in modern C++. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31   #include #include #include   int main() { std::stringstream sstr; const std::string str  = “Let’s learn from “LearnCPlusPlus.org!” “; sstr

Read More

What Is Decltype (auto) In Modern C++ And How To Use It?

The auto keyword arrives with the new features of the C++11 and the standards above. In C++14, there is a new decltype that is used with auto keyword. In modern C++, the decltype(auto) type-specifier deduces return types while keeping their references and cv-qualifiers, while auto does not. In this post, we explain what decltype (auto) is in modern C++ and how to use it. What is auto in modern C++? The auto keyword is used to define variable types automatically, it is a placeholder type specifier (an auto-typed variable), or it can be used in a function declaration, or a structured binding declaration. If you want to learn more about auto keyword, here it is, What is decltype in modern C++? The decltype keyword and operator represents the type of a given entity or expression. This feature is one of the C++11 features added to compilers (including BCC32 and other CLANG compilers). In a way you are saying “I am declaring this variable to be the same type as this other variable“. Here are more details about how you can use it, How to use decltype (auto) in modern C++? In C++14, there is a new decltype feature that allows you to use with the auto keyword. In C++14 and standards above, the decltype(auto) type-specifier deduces return types while keeping their references and cv-qualifiers, while auto does not. Since C++14, here is the syntax,   type_constraint (optional) decltype ( auto )   In this syntax, the type is decltype(expr) and expr can be an initializer or a return statement. Here is a simple example how we can use it,   decltype(auto) x = i;   Are there some simple examples about decltype (auto) in modern C++? Here are some simple examples that shows difference between auto and decltype(auto), In C++14 and above, we can use decltype(auto) with const int values as below,   const int x = 4096; auto xa = x;    // xa : int decltype(auto) xb = x;  // xb : const int   In C++14 and above, we can use decltype(auto) with int& values as below,   int y = 2048; int& y0 = y;  // y_ : int auto ya = y0;  // yc2 : int decltype(auto) yb = y0;  // yb : int&   In C++14 and above, we can use decltype(auto) with int values as below,   int&& z = 1024; auto zm = std::move(z);   // zm : int decltype(auto) zm2 = std::move(z);  // zm2 : int&&   In C++11 and above, we can use auto for return types,   auto myf(const int& i) { return i; // auto return type : int }   In C++14 and above, we can use decltype(auto) for return types,   decltype(auto) myf2(const int& i) {    return i; // decltype(auto) return type : const int& }   Is there a full example about decltype (auto) in modern C++? Here is a full example that shows how you can use auto and decltype(auto) in different int types. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54   #include   auto myf(const int& i) { return i; // auto […]

Read More

Learn How to Use New And Delete Elisions In C++

The C++14 standard (and later), brings a lot of useful smart pointers and improvements on them. They help us to avoid the mistake of incorrectly freeing the memory addressed by pointers. In modern C++, we have the new and delete operators that are used to allocate and free objects from memory, and in this post, we explain how to use new and delete operators. Can we use new and delete elisions in modern C++ or is it obsolete? Allocating memory and freeing it safely is hard if you are programming a very big application. In Modern C++, there are smart pointers that help avoid the mistake of incorrectly freeing the memory addressed by pointers. Smart pointers make it easy to define pointers, they came with C++11. The most used types of C++ smart pointer are unique_ptr, auto_ptr, shared_ptr, and weak_ptr. Smart pointers are preferable to raw pointers in many different scenarios, but there is still a lot of need to use for the new and delete methods in C++14 and above. When we develop code that requires in-place construction, we need to use new and, possibly, delete operations. They are useful, in a memory pool, as an allocator, as a tagged variant, as a buffer, or as a binary message to a buffer. Sometimes we can use new and delete for some containers if we want to use raw pointers for storage. Modern C++ has a lot of modern choices for faster and safer memory operations. Generally, developers choose to use unique_ptr/make_unique and make_shared rather than raw calls to new and delete. Even though we have a lot of standard smart pointers and abilities, we still need new and/or delete operators. How can we use new and delete elisions in C++? What is the new operator in C++? The new operator in C++, denotes a request for memory allocation on the free memory. If there is sufficient memory, a new operator initializes the memory and returns the address of the newly allocated and initialized memory to the pointer variable.    = new ;   Here, the data_type could be any built-in data type, i.e. basic C / C++ types, array, or any class types i.e. class, structure, union.  Now, let’s see how we can use new operator. We can simply use auto and new to create a new pointer and space for its buffer as below,   auto *ptr = new long int;     or in old style still you can use its type in definition instead of auto as below,   long int *ptr = new long int;     one of the great feature of pointers is we don’t need to allocate them at the beginning, we can set them NULL, and we can allocate them in some steps as below,   long int *ptr = NULL; … ptr = new long int;     What is the delete operator in C++? The delete operator in C++ is used to free the dynamically allocated array pointed by pointer variable. Here is the syntax for the delete operator,   delete ;   we can use delete[] for the pointer_arrays, here is the syntax for them,   delete[] ;   here is how we can use delete to delete a pointer, and this is how we can delete pointer arrays,   int *arr […]

Read More

What Is make_unique And How To Use With unique_ptr In C++

Allocating memory and freeing it safely is hard if you are programming a very big application. In Modern C++ there are smart pointers that help avoid the mistake of incorrectly freeing the memory addressed by pointers. Smart pointers make it easier to define and manage pointers, they came with C++11. The most used types of C++ smart pointer are unique_ptr, auto_ptr, shared_ptr, and weak_ptr. In C++14, there is make_unique (std::make_unique) that can be used to allocate memory for the unique_ptr smart pointers. What is a smart pointer and what is unique_ptr in C++? In computer science, all data and operations during runtime are stored in the memory of our computation machines (computers, IoTs, or other microdevices). This memory is generally RAM (Random Access Memory) that allows data items to be read or written in almost the same amount of time, irrespective of the physical location of data inside the memory. Allocating memory and freeing it safely is really hard if you are programming a very big application. C and C++ were notorious for making this problem even more difficult since earlier coding styles and C++ standards had fewer ways of helping developers deal with pointers and it was fairly easy to make a mistake of manipulating a pointer which had become invalid. In Modern C++, there are smart pointers that help avoid the mistake of incorrectly freeing the memory addressed by pointers which was often the source of bugs in code which could often be difficult to track down. Smart pointers make it easier to manage pointers, they came with the release of the C++11 standard. The most used types of C++ smart pointer are unique_ptr, auto_ptr, shared_ptr, and weak_ptr. std::unique_ptr is a smart pointer that manages and owns another object with a pointer, when the unique_ptr goes out of scope C++ disposes of that object automatically. If you want to do some magic in memory operations use std::unique_ptr. Here are more details on how you can use unique_ptr in C++, What is std::make_unique in C++? The std::make_unique is a new feature that comes with C++14. It is used to allocate memory for the unique_ptr smart pointers, thus managing the lifetime of dynamically allocated objects. std::make_unique template constructs an array of the given dynamic size in memory, and these array elements are value-initialized. Since C++14 to C++20, the std::make_unique function is declared as a template as below,   template unique_ptr make_unique( std::size_t size );     template unique_ptr make_unique( Args&&… args );   The std::make_unique function does not have an allocator-aware counterpart; it returns unique_ptr which would contain an allocator object and invoke both destroy and deallocate in its operator(). How to use std::make_unique with std::unique_ptr in C++? Let’s assume you have a simple class named myclass, We can create a unique pointer (a smart pointer) with this class as below,   std::unique_ptr p = std::make_unique();   Or it can be used with struct as below:   struct st_xy {     int x,y; };   We can create a unique pointer as we illustrate in the example below.   std::unique_ptr xy = std::make_unique();   We can use the auto keyword and we can define the maximum array elements like so:   auto ui = std::make_unique(5);   What are the advantages to use std::make_unique in C++? The std::make_unique function is useful when allocating smart pointer, because: We don’t need to think about new/delete or new[]/delete[] elisions. When […]

Read More

How To Use std::exchange In C++

C++ is a very precise programming language that allows you to use memory operations in a wide variety of ways. Mastering efficient memory handling will improve your app performance at run time and can result in faster applications that have optimal memory usage. One of the many useful features that come with the C++14 standard is the std::exchange algorithm that is defined in the utility header. In this post, we explain how to use std::exchange in C++. What is std::exchange in C++? The std::exchange algorithm is defined in the header and it is a built-in function that comes with C++14. The std::exchange algorithm copies the new value to a given object and it will return the old value of that object. Here is the template definition syntax (since C++14, until C++20):   template T exchange( T& object, U&& new_value );   How to use std::exchange in C++? We can use std::exchange to exchange variables values as below, and we can obtain old value from the return value of std::exchange.   int x = 500; int y = std::exchange(x, 333);   After these lines, x is now 333 and y is the old value of x , 500. We can use std::exchange to set values of object lists (i.e vectors) as shown below:   std::vector vec; std::exchange( vec, { 10, 20, 30, 40, 50 } );   In addition, we can copy old values to another object list as we show in the following example:   std::vector vec, vec0; vec0 = std::exchange( vec, { 10, 20, 30, 40, 50 } );   We can use std::exchange to change function definitions too, for example assume we have myf1() function, now we want to exchange myf() function to myf1() function, this is how we can do:   void (*myf)(); std::exchange(myf, myf1); // myf is now myf1 myf();   Is there a full example of how to use std::exchange in C++? Here is a full example of how to use std::exchange in C++. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46   #include #include   void myf1() { std::cout

Read More

What Are The Relaxed Constexpr Restrictions In C++?

In C++, the constexpr specifier is used to declare a function or variable to evaluate the value of at compile time, which speeds up code during runtime. This useful property had some restrictions in C++11, these are relaxed in C++14 and this feature is known as Relaxed Constexpr Restrictions. In this post, we explain what are the relaxed constexpr restrictions in modern C++. What is the constexpr specifier in modern C++? The C++11 standard comes with the introduction of generalized constexpr functions. The constrexpr is used as a return type specifier of function and improves performance by computations done at compile time rather than run time. Return values of constexpr could be consumed by operations that require constant expressions, such as an integer template argument. Here is the syntax:   constexpr   Here is an example of how to use a constexpr in C++:   constexpr double sq(const double x) { return ( x*x ); }   and can be used as shown below.   constexpr double y = sq(13.3);   Note that here we used a constant variable 13.3, that is given in coding, thus the result y will be calculated during compilation as 176.89. Then, we can say, similarly this line will be compiled as we show below:   const double y = 176.89   Is there a simple constexpr specifier example in modern C++? Here we can sum all above in an example. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18   #include   // C++11, a simple constexpr example constexpr double sq(const double x) { return ( x*x ); }   int main() { constexpr double y = sq(13.3); std::cout

Read More

How To Use Variable Templates In Modern C++

The template is one of the great features of modern C++. They are a simple and very powerful statement in C++ that defines the operations of a class or function. The C++14 standard and above allows the creation of variables that are templated. In this article, we will explain variable templates in C++ with examples that can be used in a professional IDE and compiler that supports C++14, C++17, and over.  First of all, let’s remind ourselves what a C++ template is. What is a template in C++? A template is a very powerful statement in C++ that simply defines the operations of a class, a function, an alias, or a variable and lets the user apply the same template on different types in those template operations. Templates are like macros in C++, considered in compilation except compiler checks types used before the template is expanded in its terms. In the compilation mechanism of a template in C++, the source code contains only a template for a function or class, but when it is compiled, the same template can be used on multiple data types. Templates are powerful entities that can be parameterized by one or more parameters. These parameters can be type template parameters, non-type template parameters, and template template parameters (parameters which are themselves templates). What is a variable template in modern C++? A variable template is used to define a family of variables or static data members. If a static data member is instantiated from a static data member template, it is called an instantiated static data member. A variable template can be introduced by a template declaration at namespace scope, where a variable declaration declares a variable. The C++14  standard and above allows the creation of variables that are templated. In C++11, only functions, classes, or type aliases could be templated.  Syntax of a variable template;   template variable_declaration   The usual rules of templates apply to such declarations and definitions, including specialization. Where is a simple variable template example in modern C++? Variable templates are used to instantiate the variables separately for the type. For example, we can assign 9.80665 to the g variable in T form ( i.e. T(9.80665) ) as a float or double or long double type and that would be g or g or g or g in template usage. Here is a simple variable template example that is used to define standard gravity value.   template constexpr T gravity = T(9.80665);   Is there a variable template instantiation example in modern C++? Now, let’s use this in a template. We can define a force template (force = mass x gravity) as shown below:   template T force(T mass) // function template { return mass*gravity; // gravity is a variable template instantiation }   here gravity is a variable template instantiation. Is there a full example of variable templates in modern C++? Here is an example variable template instantiation to different types. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29   #include   template T gravity = T(9.80665);   // template constexpr T gravity = T(9.80665);   template T force(T mass) // function template { return mass*gravity; // gravity is a variable template instantiation } int main() { auto g1 = gravity; […]

Read More

What Is Aggregate Member Initialization In C++?

The Aggregate Member Initialization is one of the features of C++. This feature is improved and modernized with C++11, C++14 and C++20. With this feature, objects can initialize an aggregate member from braced-init-list. In this post, we explain what the aggregate member initialization is and what were the changes to it in modern C++ standards. What is aggregate member initialization in modern C++? Aggregate initialization initializes aggregates. Since C++11, aggregates are a form of listed initializations. Since C++20 they are direct initializations. An aggregate could be an array or class type (a class, a struct, or a union).  Here is the general syntax,   T object = {arg1, arg2, …};   In C++11 and above, we use without = as below,   T object {arg1, arg2, …};   In C++20, there are 3 new options that we can use,   T object (arg1, arg2, …); T object = { .designator = arg1 , .designator { arg2 } … }; T object { .designator = arg1 , .designator { arg2 } … };   How to use aggregate member initialization in modern C++? C++14 provides a solution to problems in C++11 and above, for example in C++14, consider we have x, y coordinates in a struct, we can initialize them as below in a new xy object,   struct st_xy { float x, y; };   struct st_xy xy{ 3.2f, 5.1f };   In modern C++, consider that we have a struct that has a, b, c members. We initialize first two members as below,   struct st_x { short int a, b, c; };   struct st_x x{ .a = 10, .b = 20}; // x.c will be 0   We can directly initialize as below too,   struct st_y { int a = 100, b = 200, c, d; } y;   In C++17 and above, we can use this st_y as a base and we can add a new member to a new struct, then we can initialize as below,   struct st_z : st_y { int e; };   struct st_z z{ 1, 2, 3, 4, 5};   What restrictions are there for the aggregate member initialization in C++? If we consider the C++17 standard, an aggregate initialization can NOT be applied to a class type if it has one of the below, private or protected non-static data members, a constructor that is user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed), base class or classes (virtual, private, protected), virtual member functions If we consider the C++20 standard, an aggregate initialization can NOT be applied to a class type if it has one of the below, private or protected non-static data members, user-declared or inherited constructors, base class or classes (virtual, private, protected), virtual member functions Is there a full example of aggregate member initialization in C++? Here is a full example that explains simply most used features of aggregate member initialization, 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42   #include   // Aggregate in C++14 struct st_xy { float a, b; };   struct st_xy xy{ 3.2f, 5.1f };   struct st_x { […]

Read More

Learn To Use Generalized Lambda Captures In C++

Impact-Site-Verification: 9054929b-bb39-4974-9313-38176602ccee The Lambda Expression construct is introduced in C++ 11 and further developed in the C++14, C++17, and C++20 standards. C++14 standard introduced the generalized lambda capture (init capture) that allows you to specify generalized captures, it allows to use move capture in lambdas. In C++14, lambda expressions are improved by the generalized lambda (generic lambda) and by this generalized lambda captures. In this post, we explain how to use generalized lambda captures in modern C++ What is a lambda in C++? A Lambda Expression defines an anonymous function or a closure at the point where it is used. You can think of a lambda expression as an unnamed function (that’s why it’s called “anonymous”). Lambda expressions help make code cleaner, and more concise and allow you to see behavior inline where it’s defined instead of referring to an external method, like a function. Lambda Expressions are an expression that returns a function object, and they are assignable to a variable whose data type is usually auto and defines a function object. The syntax for a lambda expression consists of specific punctuation with = [ ] ( ) { … } series. If you are new to lambdas or want to know more about them, please check these two posts that we released before. How to use a generalized lambda function in C++ Before C++14, lambda function parameters need to be declared with concrete types, as in the given example above. C++14 has a new generic lambda feature that allows lambda function parameters to be declared with the auto-type specifier. The basic syntax of a Lambda Expression in C++ is; Datatype Lambda Expression = [Capture Clause] (Parameter List) -> Return Type { Body } Generalized lambdas can be defined with the auto keyword that comes with C++11. We can define a generic lambda with the auto keyword as below. auto add_things = []( auto a, auto b ) {    return a + b; }; We can use this lambda with an int type, int x = add_things( 10, 20 ); or we can use it with a float type, float f = add_things( 10.f, 20.f ); or we can use it with bool, char, double, long long double,… etc types. This is why it is called as ‘generalized‘, it is a general form that we can use with any types. Very useful and powerful. What are generalized lambda captures in C++? The Lambda Expression construct is introduced in C++ 11 and further developed in the C++14, C++17, and C++20 standards. C++14 standard introduced the generalized lambda capture (also known as init capture) that allows you to specify generalized captures. In C++14, lambda expressions are improved by the generalized lambda (generic lambda) and by this generalized lambda captures, it allows to use move capture in lambdas. A generalized capture is a new and more general capture mechanism, it allows us to specify the name of a data member in the closure class generated from the lambda, and an expression initializing that data member. Lambdas can capture expressions, rather than just variables as in functions, and this feature allows lambdas to store move-only types. How to use generalized lambda captures in C++ Let’s see how we can use generalized lambda captures in modern C++, std::move can be used to move objects in lambda captures as below, struct […]

Read More