iw4nna.rock
> for (auto & a : sprites) a.draw();
Что за a.draw() ? У тебя draw() в коде выше - это просто функция, и должно быть просто draw(), а не a.draw()
iw4nna.rock
> > Глобальная переменная, завёрнутая в namespace или структуру, не перестаёт от
> > этого быть глобальной
> Что?
То, что написано.
Глобальной переменной принято называть переменную со статическим классом памяти (static storage duration), объявленную вне функций и классов, и которая доступна всем функциям.
Заворачивание в неймспейс нисколько не меняет вышеперечисленные свойства. Да, у неё больше не global scope, а namespace scope. Но механизм namespace существует только для решения конфликта имён. И ничего больше. Даже код такой же сгенерируется. Эти переменные всё так же инициализируются на старте и доступны отовсюду (надо только писать полные имена при обращении к ним или сделать using).
Заворачивание в неймспейс ни капли не решает архитектурных проблем, за которые глобальные переменные и ругают. Просто позаворачивать глобальные переменные в namespace и сказать, что у тебя больше, якобы, нет глобальных переменных — это инфантилизм высшей степени.
MrShoor
> У тебя draw() в коде выше - это просто функция
неужели?!
Alprog
> Заворачивание в неймспейс ни капли не решает
> архитектурных проблем, за которые
> глобальные переменные и ругают.
1) я не ругаю глобальные переменные.
2) у меня нет архитектурных проблем из-за них.
> Просто позаворачивать глобальные переменные в
> namespace и сказать, что у тебя больше, якобы,
> нет глобальных переменных
где я такое говорю?
iw4nna.rock
> неужели?!
Ну так давай полный код, который компилируется тогда. Чтобы не было таких вот неужели.
Alprog
> Глобальная переменная, завёрнутая в namespace или структуру, не перестаёт от
> этого быть глобальной.
В опенгл пол-апи это выставление глобалов.
Имбирная Ведьмочка
с подвязкой на "текущий" контекст.
Который в своб очередь тред специфичный
JordanCpp
> > Вы не боитесь, что такое огромное число аргументов приведёт к падению
> > производительности?
> Не думал об этом. Есть мысли как улучшить?
передавать структуру (объект?).
Alprog
> Глобальная переменная
ох уж эти предубеждения... Конечно же глобальная переменная - это зло. Похрен, будем вызывать переменную через функцию. Так лучше, чем просто глобальная переменная.
Мы же всегда за защиту данных (обман самих себя).
iw4nna.rock
> где я такое говорю?
А где я говорю, что ты это говоришь?
> 1) я не ругаю глобальные переменные.
> 2) у меня нет архитектурных проблем из-за них.
Я рад за тебя.
По вот этой фразе ещё есть вопросы?
Глобальная переменная, завёрнутая в namespace или
структуру, не перестаёт от этого быть глобальной
iw4nna.rock
> Вы не боитесь, что такое огромное число аргументов приведёт к падению
> производительности?
твой вариант даже без относительно архитектуры еще более тормозной, компилятору в разы легче работать с локальными данными.
Mirrel
> Так лучше, чем просто глобальная переменная.
> Мы же всегда за защиту данных (обман самих себя).
Да, дело же только в этом, лол.
А ничего, что современный компайлер может передавать параметры через регистры, что быстрее рандомного доступа к памяти?
А ничего, что современный компайлер может решить заинлайнить функцию и переставить местами операции с локальными переменными ради оптимизации, а про глобальную переменную он ничего такого с уверенностью сделать не может?
А ничего, что стек всегда лежит в прогретом кэше, а глобальная переменная очень не факт?
Оптимизаторы мамкины.
Я уж молчу про какую-то возможность масштабирования программы или мультитрединг в дальнейшем.
/A\
> Почему срабатывает ассерт?
>
> struct B {
> template <typename T>
> void operator () () noexcept {}
> };
> static_assert( std::is_nothrow_invocable_v< decltype(&B::template operator()<int>) >);
decltype(&B::template operator()<int>) — это указатель-на-мембер-функцию, void (B::*)() noexcept. В обычном коде, чтобы вызвать такой указатель, тебе понадобится объект, чтобы подставить его под this. На более простом примере
struct petukh_t { char const* name; int kukarek(char const* na_kogo) const { std::cout << name << " kukarekaet na " << na_kogo << "\n"; return 10; } }; using petukh_method_t = int( petukh_t::*)( char const*) const; constexpr petukh_method_t my_petukh_method = &petukh::kukarek; int do_kukarek( ) { petukh_t vasya{"Petuh Vasya"}; return ( vasya.*my_petukh_method)( "govno"); }
Когда ты используешь инвок, объект слева от .* перемещается в позицию первого аргумента:
int do_kukarek_but_invoke() { petukh_t vasya{"Petuh Vasya"}; return std::invoke( my_petukh_method, &vasya, "govno"); }
Соответственно, когда ты проверяешь возможность вызова через инвокабл — то тебе нужно обозначить этот аргумент в констрейнте:
static_assert(std::is_invokable_v<petukh_method_t, petukh*, char const*>);
Конкретно в твоём случае:
static_assert(std::is_nothrow_invocable_v< decltype( &B::template operator( )<int>), B* >); ^^^^
Либо, конечно же, можно ещё сам оператор сделать статическим, тогда объект будет не нужен, но там уже тебе должно быть виднее.
iw4nna.rock
> Вы не боитесь, что такое огромное число аргументов приведёт к падению
> производительности?
Не надо бояться, надо реализовать оба варианта и сравнить по профайлеру, если вдруг есть опасения.
Alprog
> По вот этой фразе ещё есть вопросы?
Вы ляпнули околесицу. Такое бывает. Я вас не осуждаю за это.
Мне только не понятна ваша страсть к самобичеванию.
Если вы хотите, чтобы вас пожалели, то программирование на мой взгляд не самая удачная тема.
/A\
> Почему срабатывает ассерт?
потому что не указал класс
static_assert(std::is_nothrow_invocable_v<decltype( &B::template operator( )<int>), B>);
Имбирная Ведьмочка
> Не надо бояться, надо реализовать оба варианта и сравнить по профайлеру, если
> вдруг есть опасения.
синтетический пример скорее всего не покажет большой разницы.
> Вы ляпнули околесицу. Такое бывает. Я вас не осуждаю за это.
тебе всё верно написали, учи язык.