Category Archives: C++

An Interface Segregation Principle (ISP) example

#include <iostream>
#include <memory>
#include <string>
#include <vector>

struct IObject {
    virtual ~IObject() = default;

    /// Returns the name of the object.
    virtual std::string getName() const = 0;

    /// Prints a textual description of the object.
    virtual void describe() const = 0;

    /// Eats another object.
    virtual bool eat(IObject* other) = 0;
};
(more…)

An investigation of why dynamic_cast violates LSP

Signal sender cast in QT

QT implies that the client code will do qobject_cast that is actually dynamic_cast:

awl::ProcessTask<void> MarketModel::coPlaceOrder(OrderPtr p)
{
    // Update SQLite databse...
    // ...
    // QT signals are used in both C++ and QML.
    // They works with QObject*, and they are not aware of concrete types.
    QObject::connect(p.get(), &OrderModel::statusChanged, this, &MarketModel::onOrderStatusChanged);
}
(more…)

Examples of const function parameters in C++

Examples with int

Compiles without warnings with MSVC:

class A
{
public:

    void f(const int a);
};

void A::f(int a)
{
    a = 10;
    std::cout << a;
}
(more…)

Investigating cobalt::generator

Standard C++ generator

The code below demonstrates how standard C++23 synchronous generator works:

#include <boost/cobalt.hpp>
#include <iostream>
#include <generator>

namespace cobalt = boost::cobalt;

std::generator<int> numbers()
{
    for (int i = 1; i <= 5; ++i)
    {
        co_yield i;
    }
}
(more…)

Building boost::cobalt with MSVC 2022

cd C:\dev\repos\boost_1_89_0

set OPENSSL_ROOT_DIR=C:/dev/libs/OpenSSL
set OPENSSL_USE_STATIC_LIBS=ON
 
bootstrap.bat

b2 cxxstd=20 install --with-system --with-thread --with-cobalt --prefix=C:/dev/libs/boost_1_89_0 --toolset=msvc-14.3 -s _WIN32_WINNT=0x0A00 link=static runtime-link=static variant=release address-model=64
b2 cxxstd=20 install --with-system --with-thread --with-cobalt --prefix=C:/dev/libs/boost_1_89_0 --toolset=msvc-14.3 -s _WIN32_WINNT=0x0A00 link=static runtime-link=static variant=debug address-model=64
(more…)

An example of using base iterator in C++

The code below demonstrates how to access underlying range iterator by transformed iterator:

struct A
{
    int x;
};

struct B
{
    A* a;
};

std::vector<B> v;

int main()
{
    auto a_range = v | std::views::transform(std::mem_fn(&B::a));

    auto i = std::ranges::find(a_range, 5, std::mem_fn(&A::x));

    A* a = *i;

    B& b = *(i.base());
}
(more…)

Move assignment operator in C++

Implicitly-declared move assignment operator

If no user-defined move assignment operators are provided for a class type, and all of the following is true:

(more…)

Version tolerant serialization in C++

Last time I have been working on a C++ binary serialization framework that allows to serialize simple data structures with a few lines of code. First, you add AWL_REFLECT macro to all your structures as follows:

#include "Awl/Reflection.h"
#include <string>
#include <vector>
#include <set>

struct A
{
    int a;
    bool b;
    std::string c;
    double d;

    AWL_REFLECT(a, b, c, d)
};
(more…)

What is the type of a string literal in C++?

The code below compiles and the asserts do not fail:

#include <iostream>

int main()
{
    auto a = "str";
    const auto& ar = "str";
    const char* b = "str";
    auto const &c = a;
    auto* d = &a;
    const auto e = 2;

    static_assert(std::is_same_v<const char(&)[4], decltype("str")>);
    static_assert(std::is_same_v<const char*, decltype(a)>);
    static_assert(std::is_same_v<const char(&)[4], decltype(ar)>);
    static_assert(std::is_same_v<const char* const&, decltype(c)>);
    static_assert(std::is_same_v<const char**, decltype(d)>);
    static_assert(std::is_same_v<const int, decltype(e)>);

    std::cout << "a: " << typeid(a).name() << std::endl;
    std::cout << "ar: " << typeid(ar).name() << std::endl;
    std::cout << "b: " << typeid(b).name() << std::endl;
    
    return 0;
}

And a and b have identical typeids.

An example of overloading operator << in C++

The code below is compiled successfully with both GCC and MSVC:

#include <iostream>
#include <sstream>

template <class C>
class basic_format
{
public:
    
    template <typename T>
    basic_format & operator << (const T & val)
    {
        out << val;
        return *this;
    }

    std::basic_string<C> str() const { return out.str(); }

    operator std::basic_string<C>() const { return str(); }

private:
    
    std::basic_ostringstream<C> out;
};
(more…)