Category Archives: Programming languages

The rule of three/five/zero in C++

static_cast can’t convert from a virtual base class in C++

It converts only from non-virtual base class subobject:

struct B
{
    virtual ~B() {};
};

struct D : public virtual B { };

int main()
{
    D d;
    B& br1 = d;

    // cannot convert a 'B*' to a 'D*'; conversion from a virtual base class is implied
    // static_cast<D&>(br1); 

    dynamic_cast<D&>(br1);

    return 0;
}

Storage duration and linkage in C++

In the vernacular they say stack and heap, but the standard call this automatic and dynamic:

(more…)

How we use forwarding references with ranges in C++

The parameter or print function is a forwarding reference because the range can change while being iterated, but the current value is l-value reference:

#include <string>
#include <vector>
#include <ranges>
#include <iostream>

template <class R, class Value>
concept range_over = std::ranges::range<R> &&
    std::same_as<std::ranges::range_value_t<R>, Value>;

template <range_over<std::string> Range>
void print(Range&& range)
{
    for (const std::string& val : range)
    {
        std::cout << val << std::endl;
    }
}
(more…)

Value category is a property of an expression in C++ or std::forward explained

The code below prints l-value:

#include <iostream>

namespace
{
    void foo(const int&)
    {
        std::cout << "const l-value" << std::endl;
    }

    void foo(int&)
    {
        std::cout << "l-value" << std::endl;
    }

    void foo(int&&)
    {
        std::cout << "r-value" << std::endl;
    }
}
(more…)

The right way to capture std::unique_ptr into a lambda expression

Starting from C++14:

#include <string>
#include <memory>

int main()
{
    std::unique_ptr<std::string> p = std::make_unique<std::string>("abc");

    auto func = [p = std::move(p)]()
    {
    };

    func();

    return 0;
}
(more…)

MSVC 2022 compiler bug

Static asserts in the code below do not fail with MSVC 19.32.31332 for x86:

#include <string>

int main()
{
    std::string v = "abc";

    auto func = [v]()
    {
        auto& l_ref = v;

        static_assert(std::is_same_v<decltype(l_ref), std::string&>);

        auto&& r_ref = std::move(v);

        static_assert(std::is_same_v<decltype(r_ref), std::string&&>);
    };

    func();

    return 0;
}

that is MSVC compiler bug. With GCC both l_ref and r_ref are const references.

Thanks to stackoverflow.com.

Reported this to Microsoft.

(more…)

Switching to PHP 7.4 on Ubuntu 16.04

Some WordPress plugins stopped working with PHP 7.0 on my Ubuntu 16.04 server and I switched to PHP 7.4 with the following commands:

sudo add-apt-repository ppa:jczaplicki/xenial-php74-temp
sudo apt-get update
sudo apt-get install php7.4 php7.4-fpm php7.4-cli php7.4-mysql php7.4-dom php7.4-mbstring -y
service php7.4-fpm status
cd /etc/php/7.4/fpm/pool.d
sudo mv www.conf www.conf.dist
sudo mv ../../../7.0/fpm/pool.d/devnote.conf .
sudo service php7.0-fpm reload
sudo service php7.4-fpm reload
(more…)

An example of how r-value reference works in C++

An example of extending the lifetime of a temporary:

#include <iostream>

int main()
{
    int a = 1;
    int&& b = std::move(a);
    int&& c = b + 1;

    b = b + 1;
    c = c + 1;

    std::cout << a << b << c;
}

The output is:

223
(more…)

Using std::future as a coroutine in C++20

In C++20 it is possible to do this:

std::future<int> compute(as_coroutine) {
  int a = co_await std::async([] { return 6; });
  int b = co_await std::async([] { return 7; });
  co_return a * b;
}
 
std::future<void> fail(as_coroutine) {
  throw std::runtime_error("bleah");
  co_return;
}
 
int main() {
  std::cout << compute({}).get() << '\n';
 
  try {
    fail({}).get();
  } catch (const std::runtime_error &e) {
    std::cout << "error: " << e.what() << '\n';
  }
}
(more…)