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

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

Send message
Отличие от nullptr тут одно. С nullptr — это гарантированное UB на уровне языка в данной конкретной строке кода, независимо от поведения других частей программы. А с fake_ptr UB, если разработчик заведомо знает, что под fake_ptr реально не размещен объект (то есть, нужно знать как работает вся программа и даже оборудование, вдруг оно размещает по данному адресу объект).
Здесь в статье или в оригинале ошибка:

template<typename T> void setName(T&& _name) {
    name=std::forward<std::string>(_name);
}

std::forward<std::string>(_name) всегда вернет rvalue ссылку std::string&&, независимо от типа ссылки _name. То есть, будет работать как std::move.
Правильно std::forward<T>(_name)
Оказывается, ниже уже ответили, не дочитал. Извиняюсь.
Если точно уверен, что base_ptr указывает именно на concrete_type, то
static_cast<concrete_type*>(base_ptr)->concrete_type::function(args...)
Для плюсов:
std::tie(x, y) = getPosition();
Вот поэтому я и уточнил, что:
просматиривать глазами

А код часто приходится читать глазами в текстовых редакторах, в репозиториях… Читаемый интерфейс класса — это важно.
Мультиметоды успешно реализуются уже на текущем синтаксисе, даже на C++03: habrahabr.ru/post/155515/
Полезным с точки зрения инкапсуляции будет, как с перегрузкой операторов. Страуструп рекомендует объявлять операторы внешней функцией, если им не требуются закрытые члены. Таким образом, при проверке инвариантов и рефакторинге внутренностей мы просматриваем только операторы-члены.
Проблемы те же: интерфейс класса распадается на на члены и свободные функции, просматиривать глазами такой интерфейс неудобно, а порой и невозможно твердо понять в куче заголовочников, может ли еще где-то быть определен метод.
Отличная цитата, еле нашел habrahabr.ru/company/infopulse/blog/227529/
Самая важная фича языка

Что бы вы назвали самой важной фичей языка? (Реплики из зала: «фигурные скобки», «шаблоны»). Нет. Это деструкторы. Деструкторы сделали возможным RAII. Деструкторы упростили сложность используемых в программировании концепций на порядок. В деструкторе мы можем освободить память, мьютекс, закрыть файл или сетевое соединение. Деструкторы спасают нас от веток условий, от ненужных goto.
Вопрос «зачем?» — был не мой. Каждый свободен в выборе любимых инструментов. Меня лишь интересует техническая сторона. Как провернуть этот трюк с автоматическим деструктором на чистом C прозрачно для пользователя. Ибо это неудобство в C для меня на первом месте из-за невозможности RAII. Если это типа GCC __attribute__((cleanup (scoped))) или MSVC __try __finally. Тогда вопрос снят.
Вы сейчас о полиморфности и виртуальном деструкторе. Не спорю, это на C реализуется.

Ключевое здесь:
при том, что пользователь вызывал одну и ту же функцию «delete()»

= пользователь забыл вызвать / 2 раза вызвал / рано вызвал / не там вызвал…
В C++ RAII сделает этот вызов за вас, какой бы запутанности не был код, о чем и пытается втолковать Вам jcmvbkbc.
Очень бы хотелось увидеть пример кода, когда при выходе из области видимости в C можно исполнить некий код. Я знаю только платформозависимые конструкции, типа __try __finally в MSVC.
А насчет delete в C++: я не использую оператор delete вообще (разве что в самых низкоуровневых частях библиотек) и никому не советую. И в очень редких случаях приходится использовать new. Так что наваять new / delete на C — нет проблем, только зачем эти операторы, которые не очень согласуются с идиомами C++ (типа RAII)?
Спасибо за статью!

Пару вопросов:
1) А почему бы не использовать recursive_mutex? Или лучше задать тип мьютекса дополнительным параметром шаблона. Тогда можно и разрешить копировать Accessor, и множественно вызывать SharedResource::lock().
2) Поддержка const SharedResource намеренно отсутствует? Можно реализовать, сделав m_mutex mutable и добавив класс ConstAccessor, который будет возвращаться из SharedResource::lock() const.
так как позволяет писать
typedef TypeList<int,char,bool,string, EmptyList> MyTypeList;
вместо классической записи
typedef TypeList<int,TypeList<char,TypeList<bool,TypeList<string, EmptyList>>>> MyTypeList;

Мне не приходилось пользоваться Loki (предпочитаю boost::mpl), но, тем не менее, я заглядывал в исходники из любопытства. Там есть мейкеры для TypeList:
typedef MakeTypelist<int,char,bool,string>::Result MyTypeList;

Также на макросах:
typedef LOKI_TYPELIST_4(int,char,bool,string) MyTypeList;
Именно такой подход сразу и пришел мне в голову: через mpl::equal выражать. Это менее красиво, в разы тормознее, но формально правильно по спецификации mpl, ничего тут не поделаешь.

Справедливости ради, вместо вектора там вообще может быть все что угодно

Я о том же выше и написал, что неспецифицировано. Например, для операции mpl::erase гарантируется лишь, что результат будет «concept-identical» источнику. То есть, с сохранением набора концепций, но фиг знает каким классом.
A sequence s1 is said to be concept-identical to a sequence s2 if s1 and s2 model the exact same set of concepts.

На практике из mpl::vector[N] будет получаться mpl::vectorN-1, я бы мог забить вторую спецификацию mpl::vector1<int> и, уверен, 100 лет бы проработало, но формально — это ошибка.

принимать конкретно ваши (fas::) списки типов

К сожалению, fas — не моя, это laphroaig :)
Ни сколько не умаляю достоинств mpl. Сам пользуюсь. Ее возможности более широкие. Широченные. А за высокий уровень абстрагирования приходится платить временем компиляции.
Да, помню, как я раздосадовался, когда хотел красиво специализацией раздиспатчить что-то типа:

template <typename V>
class C{};

template <>
class C<mpl::vector<int> >{};


Не специфицировано, что может получиться после манимуляций с вектором (получится, конечно, тот же вектор как концепт, но имя у него может быть vector0, vector1 и т.д.). По факту у меня мог прийти mpl::vector1<int> или mpl::vector<int>

Пришлось извращаться менее красиво.
Кроме того boost::mpl работает с векторами, а faslib со списками

Ну почему же? MPL тоже работает со списками и с другими классами и концепциями последовательностей, а также итераторов.

А получилось здорово, конечно.
Нашему бизнесу не только пофиг. Он еще посодействовать не прочь. На примере Яндекса и LiveJournal, случайно наткнулся на этой неделе: www.e-xecutive.ru/blog/Easy_Eco/15385.php
Сам пробовал, действительно Яндекс именно ту статью про Барака не находит (хотя опубликована она на нескольких сайтах), даже если указать ему на каком сайте искать и вбивать в запрос заголовок, теги, все равно не находит. Судить не берусь, может, на это какие-то другие причины есть, не пытался исследовать, может баг. Google прекрасно выводит первыми ссылками на странице.
Полностью согласен. Можно улучшать, можно придумать еще кучу способов. Главное, что способ с std::function не единственный и далеко не самый эффективный.
А все от того, что бытует мнение, что лямбды — объекты неизвестного типа. С decltype тип вполне известен.
Стараюсь не оборачивать лишний раз лямбды в std::function из-за лишнего оверхеда, особенно, когда лямбда не влезает в small buffer optimization.
Единственным способом переместить лямбду на heap является приведение ее к типу std::function

Способ №2:
auto lamb = []() {return 5;};
auto* p = new decltype(lamb)(lamb);


Способ №3:
template <typename T>
T* heap_alloc(T const& value)
{
    return new T(value);
}

auto* p = heap_alloc([]() {return 5;});


Способ №4:
std::vector<decltype(lamb)> v;
v.push_back(lamb);

И т. д…

Information

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