Маша С++
104 subscribers
54 photos
2 files
65 links
Учу C++ и не только вместе с вами, мои котятки)
Download Telegram
В честь наступающего Нового Года запощщу тупой мем 🤩🤩
@jokespp
Please open Telegram to view this post
VIEW IN TELEGRAM
🎄31
По умолчанию, при форматировании вывода в поток булевых значений, будет использоваться
1 и 0 для true и false. Пример:

bool t = true;
bool f = false;
std::cout << t << " " << f << std::endl;
// Выведет: 1 0

Возможно, что удобнее (особенно для отладки) выводить булевы значения строкой,
также как они задаются в коде. Для этого нужно добавить в поток манипулятор boolalpha:

std::cout << std::boolalpha;
std::cout << t << " " << f << std::endl;
// Выведет: true false


Интересно то, что манипулятор действует на все последующие записи булевых значений
для этого потока. То есть он будет применяться и после ; и после std::endl.
Отменить форматирование булевых флагов можно записав в поток манипулятор
std::noboolalpha:

std::cout << std::noboolalpha << t << " " << f << std::endl; // 1 0


(Интересно, а для ввода это работает? кто проверит?)

Честно говоря, мне бы хотелось увидеть нормальные true/false по-умолчанию,
но видимо обратная совместимость.

Еще одной интересной особенностью форматирования вывода является округление
значений с плавающей точкой.
Посмотрим на вывод такого примера (на вашем окружении может быть другой результат):

double d1 = 0.1234567890;
double d2 = 0.1234564890;
std::cout << d1 << std::endl;
std::cout << d2 << std::endl;
// Вывод:
// 0.123457
// 0.123456

Поток выбрал точность в 6 знаков после точки (мы эту точность не задавали, поэтому может быть другой),
и проведет не отсечение, а округление в последней цифре.
👍3
#Шпаргалка-повторялка. Rvalue или Lvalue?

Упрощенно Lvalue (left value) это то, что стоит слева от оператора присваивания =, а rvalue (right value) справа:
lvalue = rvalue. Однако, все немного сложнее.

Если можно получить адрес некоего выражения, то зачастую это lvalue. Если нельзя - то это обычно rvalue.

Rvalue концептуально часто временный объект без имени (например результат работы функции, временное значение, литерал).
А вот lvalue обычно имеет имя.

А еще rvalue могут быть перемещены, но об этом в другой раз.
👍3🔥2
Использует ли std::optional указатели для реализации?

Нет. std::optional не выделяет память в куче, он может полностью работать на стеке.

Объект создается на месте в стековом куске памяти (размером с объект) внутри опшинала.
Поэтому нет и накладных расходов на переход по указателю (но есть накладные расходы на bool флаг для состояния инициализации + выравнивание).

Однако возникает вопрос, расходует ли std::optional память под неинициализированный объект? Ведь хранилище выделятся всегда на стеке. Думаю, что вы можете ответить на него самостоятельно (а еще посмотреть на sizeof для жирного объекта).

Выходит, что std::optional и не такой уж optional, память то всегда жрет)

Кстати, по причине такой реализации optional нельзя создавать с некоторыми типами, например не пойдут cсылки, функции, void, массивы.
👍21🔥1
Интересна ли тема Qt?

Сегодня речь пойдет про QPointer. Как известно, в Qt всё строится вокруг QObject со своей механикой владения объектами, отличной от использования "стандартных" умных указателей, типа std::shared_ptr.

Давайте посмотрим на такой пример: в наш класс передается некий наследник QObject, которым мы не владеем. Далее в какой-то момент времени нам необходимо удостовериться, а существует ли этот объект еще или нет.

struct Class: {
Class(QObject * obj) : obj_(obj) {}

void do() {
if (obj_) { // жив ли объект по указателю?
//obj_->method(); // UB, если нет
};
}

QObject * obj_;
};


В стандартном C++ мы бы воспользовались weak_ptr. Но в Qt есть специальный класс с довольно абстрактным названием QPointer, который ведет себя как обычный сырой указатель, однако автоматически очищается когда хранимый им указатель удаляется. Поэтому мы можем проверить, удалился ли объект по указателю.

Внесем простые изменения в класс:
QPointer<QObject> * obj_;
Теперь проверка if (obj_) будет работать как ожидается, при этом нам не обязательно оборачивать указатель в QPointer при передаче в конструктор класса.

В чем отличия от weak/shared ptr? Во-первых не нужно изначально оборачивать указатель в shared, что может быть не всегда и возможно. Во-вторых работает только с наследниками QObject. Ну и механизм работы отличается, что кстати может легко сломаться в многопоточном коде.

О мёртвых указателях либо хорошо, либо ничего.
👍5😁2🔥1
#мем что ли выложить
Идет корова по лесу, видит, проект горит. Села в нее и выгорела.
😁7
Начиная с С++23 официально доступны директивы #elifdef и #elifndef, так что теперь например вместо:

#ifdef WINDOWS
//
#elif defined(MACOS)
//
#elif defined(LINUX)
//
#endif

можно будет писать короче и консистентнее:

#ifdef WINDOWS
//
#elifdef MACOS
//
#elifdef LINUX
//
#endif

Краткость — сестра таланта (и брат нового стандарта)
👍51
Утверждён стандарт C++26.
Мне понравились новые няшные операторы ^^ 😇:
static_assert(^^i != ^^j);
https://www.opennet.ru/opennews/art.shtml?num=65102
Please open Telegram to view this post
VIEW IN TELEGRAM
😁5👍1
Чистовик: Сайт отслеживает переход популярных проектов на модули C++. По прогнозу к 2167 году переедут все 😛:
https://arewemodulesyet.org/
Please open Telegram to view this post
VIEW IN TELEGRAM
4😁3🔥1