В современном С++ мы можем писать например так:
Обычно так и я пишу свой код на работе.
А можем написать вот так, мерко, противно, императивно:
std::for_each(threads.begin(), threads.end(), std::mem_fun_ref(&std::thread::join));Это очень круто, мы пишем в близком к функциональному подходу стиле и читается это как настоящий язык: для каждого потока от начала до конца вызови функцию по ссылке - соединиться.
Обычно так и я пишу свой код на работе.
А можем написать вот так, мерко, противно, императивно:
for(auto& t: threads)Так я пишу свой код на работе после того как удалил тот, что написал сначала.
t.join();
На каком языке пишите (в основном)?
Anonymous Poll
5%
C
16%
С++
12%
Java
11%
JavaScript
26%
Python
11%
Go
3%
Scala
3%
Haskell
5%
PHP
9%
Другое, напишу в комментах
Forwarded from Hermitage
RPCS3, эмулятор PlayStation 3 под PC (Windows/Linux), здорово развивается — удалось запустить эксклюзивный консольный тайтл Metal Gear Solid 4. Игра функционально в рабочем состоянии, но остались графические баги и артефакты. Есть надежда, что это решаемые баги эмуляции GPU и в ближайшее время они будут устранены. Забавно, но эмулятор уже позволяет снять ограничение в 30fps и играть на 60fps.
YouTube
RPCS3 - Metal Gear Solid 4 Ingame for the first time!
The promised day has finally arrived! Thanks to the recent improvement made by eladash, the coveted PlayStation exclusive title, Metal Gear Solid 4, now goes...
https://twitter.com/ericniebler/status/1167172402184216576
Эрик Ниблер жарит ваще адовые библиотеки, аж время компиляции отклеивается.
Для этого примера это 4.5 секунды с использованием clang.
Эрик Ниблер жарит ваще адовые библиотеки, аж время компиляции отклеивается.
Для этого примера это 4.5 секунды с использованием clang.
Я сейчас в шоке, но уже почти отошел.
Выяснилось, что все это время в С++ можно было так
Чуть легче мне стало, когда мне сказали, что все-таки это не по стандарту.
Я перебрал кучу компиляторов и версий языка - можно! Только clang 3.2 сдался, а g++ ниже 4.1.2 не нашел.
А потом я добрался до msvc и увидел заветное
Выяснилось, что все это время в С++ можно было так
#include <iostream>Т.е. создавать массив динамического размера на стеке! Вот так просто! А я к ЕГЭ готовился и new/delete осваивал, чтобы задачки закодить как надо.
int main() {
size_t size;
std::cin >> size;
int array[size];
}
Чуть легче мне стало, когда мне сказали, что все-таки это не по стандарту.
Я перебрал кучу компиляторов и версий языка - можно! Только clang 3.2 сдался, а g++ ниже 4.1.2 не нашел.
А потом я добрался до msvc и увидел заветное
error C2131: expression did not evaluate to a constant
Я до 2018 года только msvc пользовался и знать не знал какая жуть может происходить. Мне нужно выпить.Сегодня задачка по С++, вопрос простой - что не так? Если хочется подумать самостоятельно, то сначала прочитайте код, высказывайтесь в комментариях, а потом читайте дальше.
И я интересуюсь: "Где мое позднее связывание, ̶Л̶е̶б̶о̶в̶с̶к̶и̶ ?"
На что получаю резонное замечание от привлеченных специалистов из крупных международных компаний: "А, собственно, почему оно должно работать? Ты в деструкторе по факту вызываешь виртуальную функцию, наследник уже мертв в этот момент".
Вот такой вот способ выстрелить себе в ногу с двух ̶р̶у̶к̶ потоков.
#include <iostream>Собираем
#include <memory>
#include <thread>
class Base{
public:
virtual ~Base() {
thread.join();
}
void proc() {
thread = std::thread(&Base::foo, this);
}
virtual void foo() {
std::cout << bar() << std::endl;
}
virtual std::string bar() = 0;
std::thread thread;
};
class Child : public Base
{
public:
std::string bar() override { return "Child"; }
};
class Derived : public Base
{
public:
std::string bar() override { return "Derived"; }
};
int main()
{
auto c = std::make_unique<Child>();
auto d = std::make_unique<Derived>();
c->proc();
d->proc();
}
g++ -O3 -pthread main.cpp и программа падает на вызове чисто виртуальной функции. Наша редакция прибегла к помощи специалистов и путем нехитрых манипуляций внесла изменения в кодvirtual std::string bar() { return "Base"; };
Теперь вывод, казалось бы, должен быть очевиден, но нет:DerivedПеребрав несколько компиляторов и окружений, все таки стало понятно, что бывает и ожидаемый вариант
Base
Base
Base
И я интересуюсь: "Где мое позднее связывание, ̶Л̶е̶б̶о̶в̶с̶к̶и̶ ?"
На что получаю резонное замечание от привлеченных специалистов из крупных международных компаний: "А, собственно, почему оно должно работать? Ты в деструкторе по факту вызываешь виртуальную функцию, наследник уже мертв в этот момент".
class Base{
public:
virtual ~Base() = default;
void wait() { thread.join(); }
...
};
class Child : public Base
{
public:
~Child() { wait(); }
std::string bar() override { return "Child"; }
};
class Derived : public Base
{
public:
~Derived() { wait(); }
std::string bar() override { return "Derived"; }
};
Т.е. по мере разрушения у объектов менялись таблицы виртуальных функций и иногда одному из них везло, а второму не везло никогда.Вот такой вот способ выстрелить себе в ногу с двух ̶р̶у̶к̶ потоков.
🦖 Айти Тудэй 🦥
Сегодня задачка по С++, вопрос простой - что не так? Если хочется подумать самостоятельно, то сначала прочитайте код, высказывайтесь в комментариях, а потом читайте дальше. #include <iostream> #include <memory> #include <thread> class Base{ public: virtual…
Поступило сразу несколько вопросов, а с прода ли этот код? Так вот нет, потому что я сначала написал тесты :)