All streams
Search
Write a publication
Pull to refresh
39
0
Виктор Щерба @vScherba

Разработчик C++

Send message
Эти костыли не просто так появились. Boost.Graph широко использует их. Сходу нагуглил: тут вроде обосновывают.
Мне кажется, что под Boost.Graph их и разрабатывали. Не знаю, как объявлять такие функции, а использовать вполне удобно.
Мы с женой совсем не похожи, ну, может, чуть-чуть. С другими девушками, такими занудливыми, как я, мне хватало месяца общения, чтобы потерять интерес :)
Спасибо, за статью!

Если производительность критична, то в последнем примере я бы не стал заворачивать лямбду в function. Зачем лишние накладные расходы на упаковку и полиморфный вызов?

auto lambda = [](HMODULE* instance){ FreeLibrary(*instance); };
auto my_instance = std::unique_ptr<HMODULE, decltype(lambda)>
    (new HMODULE(LoadLibrary(_T("my_library.dll"))), lambda);
FreeLibrary(*instance) теперь просто заинлайнится.

Здесь еще более серьезная проблема в том, что Вы выделяете через new HMODULE память под хендл в куче и не освобождаете ее, Вы ведь заместили deleter по-умолчанию своим, не так ли? Исправляем вот так:
auto lambda = [](HMODULE* instance){ FreeLibrary(*instance); delete instance;};


В итоге, я бы извратился еще проще:

auto lambda = [](HINSTANCE instance){ FreeLibrary(instance); };
auto my_instance = std::unique_ptr<HINSTANCE__, decltype(lambda)>
    (LoadLibrary(_T("my_library.dll")), lambda);

Никаких new, delete и куч. Для shared_ptr примера то же самое.

С Наступающим, Вас и всех!
В данном варианте можно отключить RTTI в настройках компилятора (зачем? отдельный вопрос). А dynamic_cast без RTTI не работает. Если это библиотечный код общего назначения, то именно так и должно быть реализовано.
Я никогда не пробовал дружить код разных компиляторов на уровне классов C++, поэтому не смогу что-то Вам посоветовать. Но уверен, проблем с этим выше крыши. Даже при передаче банального std::string через границу модулей, собранных разными компиляторами, нет никаких гарантий совместимости. А точнее, гарантированы проблемы: бинарной совместимости нет.
Вряд ли. std::type_info в разных компиляторах скорее всего будет реализован по-разному. Поэтому, сравнивать 2 ссылки на type_info от разных компиляторов опасно для приложения.
Благодаря этому подходу, реализованы std::function, boost::function, boost::any. Про преимущества boost::any можно разговаривать, но без (std|boost)::function жизнь в C++ тяжела.

А Вы пробовали компилировать Ваш код? dynamic_cast от void* не работает. dynamic_cast работает на полиморфных типах.
Посмотрите, как красиво и насколько обобщенно реализована идиома Type Erasure в Boost by Steven Watanabe.
Вы ошиблись насчет RTTI:
Для этого, к сожалению, нам придется воспользоваться RTTI.

return typeid(t_);


В этом варианте использования typeid не задействует механизм RTTI, т.к. реальный статический тип переменной t_ известен на этапе компиляции (RTTI включается, когда typeid принимает ссылку на полиморфный тип). Вы можете в этом убедиться, отключив в настройках компиляции поддержку RTTI.

Я бы поправил код вот так, чтобы избежать сомнений:
return typeid(T);
Или boost::scoped_ptr.
Вот тут и выясняется, что у каждого путешествующего программиста есть скрипт в загашнике )

Спасибо за скрипт! Вы молодец, что докопались. Я с наскока не смог обойти защиту, стал мониторить более простым способом: скриптом с GET-запросом на Яндекс.Расписания:
rasp.yandex.ru/buy/options/?number=154А&thread=154AB_tis&t_type=train&station_to=9602494&station_from=2006004&date=2014-01-01
Запрос возвращает либо «retrieving», либо ответ в формате JSON.
Выяснил также, что сервис Яндекса обновляет данные из базы РЖД с некоторым интервалом, из-за этого билет на Яндексе может появиться на несколько минут позже. Забыл уже, где-то около 2-х минут разница, но этих пару минут хватает, чтобы билет уже кто-то увел.

Плюс Яндекса в том, что можно мониторить билеты на любой транспорт.
Исходящие лучи, отраженные от тарелки имеют ту же геометрию, что и входящие, только направлены в противоположную сторону.
Если бы радиоволны были видны, то облучатель светился бы как лампочка, а тарелка выглядела как отражатель в фонарике, а вся конструкция похожа на фонарик, узкий луч которого светит прямо на базовую станцию.
То есть волна не рассеивается во всех направлениях, уменьшаясь в мощности пропорционально квадрату расстояния, а передается, сохраняя плотность своей энергии (в идеальных условиях, конечно).
Чего-то стали минусовать не разобравшись. sizeof(t1) == sizeof(t2) действительно применимо именно в рассматриваемом случае, когда возвращаемым типам разных функций заданы заведомо разные размеры. Я думаю, именно это имел в виду AxisPod. См. пример в моем комменте, там же про static_cast<T*>(0).
В Вашей реализации есть неточность: она будет детектировать сигнатуры не только foo(int), но и foo(long), foo(float) и т.д.

Я предлагаю тестировать на получение указателя на метод с определенной сигнатурой:

template<typename T> struct has_foo
{
private:  // Спрячем от пользователя детали реализации.
    template <typename U, void(U::*pfn)(int) = &U::foo>
    struct detector {char _[2];};

    static char detect(...);  // Статическую функцию и вызывать проще.
    template<typename U> static detector<U> detect(U*);
public:
    static const bool value = sizeof(detect(static_cast<T*>(0))) != sizeof(char);  // Вот видите, готово.
};


Проверяет на точное совпадение сигнатуры void foo(int). Как видите, обошлось стандартом C++03, и все довольно просто.
Интересно, а что получится, если движение кругов из рисунка Симпсона отобразить синусоидой и проиграть ее как звуковую волну? Скорее всего, гармонии там не будет наблюдаться.
Отсюда вытекает еще вопрос: а можно ли придумать осмысленные картинки с осмысленным гармоничным звучанием?
Просветление оптики сокращает потери света на отражении от раздела 2-х оптических сред. Поэтому, тут этот эффект мог бы быть полезен только, если наносить просветляющий слой на внутреннюю поверхность экрана.
Вступлюсь за автора. Статья интересно написана. Думаю, что код не для продакшн. А для статьи он хорошо подходит. Для беглого просмотра именно такой код и должен быть: максимально упрощен, типы максимально конкретизированы. Легче вникать. На исключения можно было вообще забить, кода и так очень много, не все до конца доберутся.
Я видел это в статье, но счел за шутку. Мне показалось, что были дополнительные причины, по которым coroutine не удалось прикрутить.
Ну, автор мог бы не реализовывать свою корутину на базе Boost.Context, а заюзать Boost.Coroutine, которая как раз сама все это делает и на базе той же Boost.Context.
Спасибо, за статью. А почему не захотели Boost.Coroutine использовать?

Information

Rating
Does not participate
Location
Дубна, Москва и Московская обл., Россия
Date of birth
Registered
Activity