Shaylee  Lemke

Shaylee Lemke

1596471594

Applying Curiously Recurring Template Pattern in C++

Curiously Recurring Template Pattern(CRTP) in C++ is definitely a powerful technique and a static alternative to virtual functions. But at the same time, learning it may seem a bit weird at first. If you are like me who struggled to grasp anything in one go. Then this article might help you to provide a thought process on where CRTP fits in day-to-day coding. And, if you are an Embedded Programmer, you may run into CRTP more often. Although, std::variant + std::visit will also help but 90% of the compilers for embedded processors are either not up to date with standard or dumb.

There is various material effectively accessible for “How” and “What” on CRTP. So, I will address the “Where” part that CRTP Applicability.

CRTP and Static Polymorphism In C++

C++

template<typename specific_animal>
struct animal {
    void who() { static_cast<specific_animal*>(this)->who(); }
};
struct dog : animal<dog> {
    void who() { cout << "dog" << endl; }
};
struct cat : animal<cat> {
    void who() { cout << "cat" << endl; }
};
template<typename specific_animal>
void who_am_i(animal<specific_animal> andanimal) {
    animal.who();
}
cat c;
who_am_i(c); // prints `cat`
dog d;
who_am_i(d); // prints `dog`
  • Curiously Recurring Template Pattern widely employed for static polymorphism without bearing the cost of a virtual dispatch mechanism. Consider the above code, we haven’t used virtual keyword and still achieved the functionality of polymorphism.
  • How it works is not the topic of this article. So, I am leaving it to you to figure out.

Limiting Object Count With CRTP

  • There are times when you have to manage the critical resource with single or predefined object count. And we have Singleton and Monotone Design Patterns for this. But this works as long as your object counts are smaller in number.
  • When you want to limit the arbitrary type to be limited with an arbitrary number of instances. CRTP will come to rescue:

C++

template <class ToBeLimited, uint32_t maxInstance>
struct LimitNoOfInstances {
    static atomic<uint32_t> cnt;
    LimitNoOfInstances() {
        if (cnt >= maxInstance)
            throw logic_error{"Too Many Instances"};
        ++cnt;
    }
    ~LimitNoOfInstances() { --cnt; }
}; // Copy, move & other sanity checks to be complete
struct One : LimitNoOfInstances<One, 1> {};
struct Two : LimitNoOfInstances<Two, 2> {};
template <class T, uint32_t maxNoOfInstace>
atomic<uint32_t> LimitNoOfInstances<T, maxNoOfInstace>::cnt(0);
void use_case() {
    Two _2_0, _2_1;
    try {
        One _1_0, _1_1;
    } catch (exception &e) {
        cout << e.what() << endl;
    }
}
  • You might be wondering that what is the point of the template parameter ToBeLimited, if it isn’t used. In that case, you should have brush up your C++ Template fundamentals or use cppinsights.io. As it isn’t useless.

CRTP to Avoid Code Duplication

  • Let say you have a set of containers that support the functions begin() and end(). But, the standard library’s requirements for containers require more functionalities like front()back()size(), etc.
  • We can design such functionalities with a CRTP base class that provides common utilities solely based on derived class member function i.e. begin() and end() in our cases:

C++

template <typename T>
class Container {
    T &actual() { return *static_cast<T *>(this); }
    T const &actual() const { return *static_cast<T const *>(this); }
public:
    decltype(auto) front() { return *actual().begin(); }
    decltype(auto) back() { return *std::prev(actual().end()); }
    decltype(auto) size() const { return std::distance(actual().begin(), actual().end()); }
    decltype(auto) operator[](size_t i) { return *std::next(actual().begin(), i); }
};
  • The above class provides the functions front()back()size() and operator[ ] for any subclass that has begin() and end().
  • For example, subclass could be a simple dynamically allocated array as:

C++

template <typename T>
class DynArray : public Container<DynArray<T>> {
    size_t m_size;
    unique_ptr<T[]> m_data;
  public:
    DynArray(size_t s) : m_size{s}, m_data{make_unique<T[]>(s)} {}
    T *begin() { return m_data.get(); }
    const T *begin() const { return m_data.get(); }
    T *end() { return m_data.get() + m_size; }
    const T *end() const { return m_data.get() + m_size; }
};
DynArray<int> arr(10);
arr.front() = 2;
arr[2]        = 5;
asssert(arr.size() == 10);

#web dev #c++ 11 #crtp #c++ #cplusplus #programming-c

What is GEEK

Buddha Community

Applying Curiously Recurring Template Pattern in C++
Shaylee  Lemke

Shaylee Lemke

1596471594

Applying Curiously Recurring Template Pattern in C++

Curiously Recurring Template Pattern(CRTP) in C++ is definitely a powerful technique and a static alternative to virtual functions. But at the same time, learning it may seem a bit weird at first. If you are like me who struggled to grasp anything in one go. Then this article might help you to provide a thought process on where CRTP fits in day-to-day coding. And, if you are an Embedded Programmer, you may run into CRTP more often. Although, std::variant + std::visit will also help but 90% of the compilers for embedded processors are either not up to date with standard or dumb.

There is various material effectively accessible for “How” and “What” on CRTP. So, I will address the “Where” part that CRTP Applicability.

CRTP and Static Polymorphism In C++

C++

template<typename specific_animal>
struct animal {
    void who() { static_cast<specific_animal*>(this)->who(); }
};
struct dog : animal<dog> {
    void who() { cout << "dog" << endl; }
};
struct cat : animal<cat> {
    void who() { cout << "cat" << endl; }
};
template<typename specific_animal>
void who_am_i(animal<specific_animal> andanimal) {
    animal.who();
}
cat c;
who_am_i(c); // prints `cat`
dog d;
who_am_i(d); // prints `dog`
  • Curiously Recurring Template Pattern widely employed for static polymorphism without bearing the cost of a virtual dispatch mechanism. Consider the above code, we haven’t used virtual keyword and still achieved the functionality of polymorphism.
  • How it works is not the topic of this article. So, I am leaving it to you to figure out.

Limiting Object Count With CRTP

  • There are times when you have to manage the critical resource with single or predefined object count. And we have Singleton and Monotone Design Patterns for this. But this works as long as your object counts are smaller in number.
  • When you want to limit the arbitrary type to be limited with an arbitrary number of instances. CRTP will come to rescue:

C++

template <class ToBeLimited, uint32_t maxInstance>
struct LimitNoOfInstances {
    static atomic<uint32_t> cnt;
    LimitNoOfInstances() {
        if (cnt >= maxInstance)
            throw logic_error{"Too Many Instances"};
        ++cnt;
    }
    ~LimitNoOfInstances() { --cnt; }
}; // Copy, move & other sanity checks to be complete
struct One : LimitNoOfInstances<One, 1> {};
struct Two : LimitNoOfInstances<Two, 2> {};
template <class T, uint32_t maxNoOfInstace>
atomic<uint32_t> LimitNoOfInstances<T, maxNoOfInstace>::cnt(0);
void use_case() {
    Two _2_0, _2_1;
    try {
        One _1_0, _1_1;
    } catch (exception &e) {
        cout << e.what() << endl;
    }
}
  • You might be wondering that what is the point of the template parameter ToBeLimited, if it isn’t used. In that case, you should have brush up your C++ Template fundamentals or use cppinsights.io. As it isn’t useless.

CRTP to Avoid Code Duplication

  • Let say you have a set of containers that support the functions begin() and end(). But, the standard library’s requirements for containers require more functionalities like front()back()size(), etc.
  • We can design such functionalities with a CRTP base class that provides common utilities solely based on derived class member function i.e. begin() and end() in our cases:

C++

template <typename T>
class Container {
    T &actual() { return *static_cast<T *>(this); }
    T const &actual() const { return *static_cast<T const *>(this); }
public:
    decltype(auto) front() { return *actual().begin(); }
    decltype(auto) back() { return *std::prev(actual().end()); }
    decltype(auto) size() const { return std::distance(actual().begin(), actual().end()); }
    decltype(auto) operator[](size_t i) { return *std::next(actual().begin(), i); }
};
  • The above class provides the functions front()back()size() and operator[ ] for any subclass that has begin() and end().
  • For example, subclass could be a simple dynamically allocated array as:

C++

template <typename T>
class DynArray : public Container<DynArray<T>> {
    size_t m_size;
    unique_ptr<T[]> m_data;
  public:
    DynArray(size_t s) : m_size{s}, m_data{make_unique<T[]>(s)} {}
    T *begin() { return m_data.get(); }
    const T *begin() const { return m_data.get(); }
    T *end() { return m_data.get() + m_size; }
    const T *end() const { return m_data.get() + m_size; }
};
DynArray<int> arr(10);
arr.front() = 2;
arr[2]        = 5;
asssert(arr.size() == 10);

#web dev #c++ 11 #crtp #c++ #cplusplus #programming-c

Tamale  Moses

Tamale Moses

1624240146

How to Run C/C++ in Sublime Text?

C and C++ are the most powerful programming language in the world. Most of the super fast and complex libraries and algorithms are written in C or C++. Most powerful Kernel programs are also written in C. So, there is no way to skip it.

In programming competitions, most programmers prefer to write code in C or C++. Tourist is considered the worlds top programming contestant of all ages who write code in C++.

During programming competitions, programmers prefer to use a lightweight editor to focus on coding and algorithm designing. VimSublime Text, and Notepad++ are the most common editors for us. Apart from the competition, many software developers and professionals love to use Sublime Text just because of its flexibility.

I have discussed the steps we need to complete in this blog post before running a C/C++ code in Sublime Text. We will take the inputs from an input file and print outputs to an output file without using freopen file related functions in C/C++.

#cpp #c #c-programming #sublimetext #c++ #c/c++

Dicey Issues in C/C++

If you are familiar with C/C++then you must have come across some unusual things and if you haven’t, then you are about to. The below codes are checked twice before adding, so feel free to share this article with your friends. The following displays some of the issues:

  1. Using multiple variables in the print function
  2. Comparing Signed integer with unsigned integer
  3. Putting a semicolon at the end of the loop statement
  4. C preprocessor doesn’t need a semicolon
  5. Size of the string matters
  6. Macros and equations aren’t good friends
  7. Never compare Floating data type with double data type
  8. Arrays have a boundary
  9. Character constants are different from string literals
  10. Difference between single(=) and double(==) equal signs.

The below code generates no error since a print function can take any number of inputs but creates a mismatch with the variables. The print function is used to display characters, strings, integers, float, octal, and hexadecimal values onto the output screen. The format specifier is used to display the value of a variable.

  1. %d indicates Integer Format Specifier
  2. %f indicates Float Format Specifier
  3. %c indicates Character Format Specifier
  4. %s indicates String Format Specifier
  5. %u indicates Unsigned Integer Format Specifier
  6. %ld indicates Long Int Format Specifier

Image for post


A signed integer is a 32-bit datum that encodes an integer in the range [-2147483648 to 2147483647]. An unsigned integer is a 32-bit datum that encodes a non-negative integer in the range [0 to 4294967295]. The signed integer is represented in twos-complement notation. In the below code the signed integer will be converted to the maximum unsigned integer then compared with the unsigned integer.

Image for post

#problems-with-c #dicey-issues-in-c #c-programming #c++ #c #cplusplus

Ari  Bogisich

Ari Bogisich

1590587580

Loops in C++ | For, While, and Do While Loops in C++

In this Video We are going to see how to use Loops in C++. We will see How to use For, While, and Do While Loops in C++.
C++ is general purpose, compiled, object-oriented programming language and its concepts served as the basis for several other languages such as Java, Python, Ruby, Perl etc.

#c #c# #c++ #programming-c

Ari  Bogisich

Ari Bogisich

1589816580

Using isdigit() in C/C++

In this article, we’ll take a look at using the isdigit() function in C/C++. This is a very simple way to check if any value is a digit or not. Let’s look at how to use this function, using some simple examples.

#c programming #c++ #c #c#