170 похожих чатов

Может есть какой-то референс по плюсам где расписаны все эти

наследования и дикие шаблоны?

18 ответов

17 просмотров

ты хочешь знать как работает std ?

вы смотрите на внутренности стандартной библиотеки, так что никакие референсы, кроме референса по вашей реализации стандартной библиотеки, в принципе не могут вам помочь

Vlad
вы смотрите на внутренности стандартной библиотеки...

Здравствуйте. Как вы считаете, прав ли в данной ситуации кланг? https://godbolt.org/z/9P9o771bT учитывая https://eel.is/c++draft/temp.spec#temp.inst-3

Liber Azerate
Здравствуйте. Как вы считаете, прав ли в данной си...

любопытно, что он считает себя правым аж с версии 3.4 (более старые не умеют в iostream почему-то). мое собственное мнение пока в процессе формирования

Vlad
любопытно, что он считает себя правым аж с версии ...

Если хотите, можете посмотреть(или присоединиться) уже состоявшееся обсуждение: https://t.me/stdvector/588553

Liber Azerate
Здравствуйте. Как вы считаете, прав ли в данной си...

если коротко, то не прав, на мой взгляд если длинно, то (1) неявная инстанциация определения S<int> ведет к неявной инстанциации декларации шаблона operator[] на строке 13 (temp#inst-3.1). (2) далее вызов a[1] должен разрешиться в пользу декларации, инстанцированной из шаблона на строке 13 (temp#inst-10) (*), (3) что ведет к неявной инстанциации уже определения operator[] из того же шаблона (temp#inst-4), что (4) позволит компилятору вывести возвращаемый тип (dcl.spec.auto#general-12) * в том, что это возможно при помощи одной лишь декларации без вывода возвращаемого типа, я убедился полнотекстовым поиском return, dedu, definition и placeholder по главе [over] clang же ломается, как я понимаю, где-то между шагами 2 и 3, считая, что перегрузка не может разрешиться в функцию, возвращаемый тип которой не выведен, но он не может его вывести, пока не выберет ее и не инстанцирует определение пошерстил CWG issues, но ничего не нашел. но там столько, что я вполне мог что-то упустить меня сбило с толку, что этот шаблон на строке 13 одновременно и member template specialization (temp.expl.spec-15) с точки зрения класса, который для целей инстанциации определения класса является declared specialization (temp.spec#temp.expl.spec-1.9, temp.spec#temp.inst-1), но после нее становится обычным member function template, который требует неявной инстанциации всего. еще я не нашел, что такое инстанциация, когда не указывается, инстанциация это декларации или же определения. буду рад, если кто-то докажет, что я слепой

Vlad
если коротко, то не прав, на мой взгляд если длин...

А в пункте 1 неявно инстанцируется декларация на строке 8 или 13 всё же? Спасибо за ваш подробный разбор :)

Liber Azerate
А в пункте 1 неявно инстанцируется декларация на с...

8 это всего лишь primary template, который ведет к специализации на строке 13

Vlad
8 это всего лишь primary template, который ведет к...

То есть декларация из основного шаблона вообще не инстанцируется? Ибо меня явно ввёл в заблуждение данный пример: https://eel.is/c++draft/temp#inst-example-3 Он, кстати, забавен тем, что несмотря на подпись ни в одном из компиляторов не падает

Liber Azerate
То есть декларация из основного шаблона вообще не ...

да, не инстанцируется, аналогично template<typename T> class A { /* def1 */ }; template<> class A<int> { /* def2 */ }; A<int> a; def1 вообще не интересен и его может вовсе не быть, если я все правильно понимаю

Liber Azerate
То есть декларация из основного шаблона вообще не ...

насчет примера: // OK, definition of C<void>​::​f is not instantiated at this point — это работает the implicit instantiation of the declarations, but not of the definitions, of the non-deleted class member functions из первого подпункта // error: redefinition of C<int>​::​g — это работает the implicit instantiation of the definitions of deleted member functions из второго подпункта

Vlad
насчет примера: // OK, definition of C<void>​::​f...

Да, но откуда там берётся инстанцировение определения удалённой функции, если на основной шаблон мы даже не смотрим?

Liber Azerate
Да, но откуда там берётся инстанцировение определе...

здесь речь об инстанциации класса, а выше мы говорили об инстанциации шаблона функции-члена (когда выбирали между 8 и 13 строками). мне развить мысль или и так понятно?

Vlad
здесь речь об инстанциации класса, а выше мы говор...

А можно всё же разъяснения? :) Простите. Меня интересует сейчас в первую очередь этот пример из стандарта. Я просто не улавливаю логики. Более того, глядя на пример ниже, становится жутко от возможностей С++... #include <iostream> template<typename T> struct X { void foo() {} void bar() {} }; template<> void X<int>::bar() { std::cout << "bar\n"; } int main(int argc, char *argv[]) { X<int> x; x.bar(); x.foo(); } И непонятно, как это вообще работает, однако согласно https://eel.is/c++draft/temp#inst-3.1 это по идее, верно(?). Моё предположение было в том, что наличие такой частичной специализации метода как бы действительно инстанцирует весь класс с данным типом, создавая и все методы заодно, а т.к. мы создаём как бы перегрузку одного из методов, то рассматривается сигнатура данного метода. И в случае = delete метода для конкретно такой ситуации её определение становится частью объявления, и поэтому на основе несоответствия сигнатур такая частичная специализация метода должна отвергаться, однако если я правильно мыслю(?), то почему разрешено(?) переопределить в частичной специализации метод, с уже наличествующим определением? То есть оба этих определения существуют, но конкретная специализация создаётся именно с определением наиболее специализированного метода? И почему тогда всё же играет роль = delete, если можно было бы точно так же просто откинуть это определение?

Liber Azerate
А можно всё же разъяснения? :) Простите. Меня инте...

в первую очередь хочу отметить, что ни раньше, ни сейчас речь не шла о частичных специализациях — только о полных. у меня есть представление, как они работают, но нам сейчас они вообще не нужны. у вас столько вопросов, что, полагаю, есть смысл разобрать следующий пример: #include <iostream> template<typename T> struct X { void foo() { std::cout << "foo in-class"; } // deleted __definition__ // declaration would be void bar() void bar() = delete; void baz() { std::cout << "baz in-class"; } void qux() = delete; }; // specialization 1 template<> void X<int>::foo() { std::cout << "foo spec"; } // specialization 2 template<> void X<int>::bar() { std::cout << "bar spec"; } int main() { X<int> x; // 1 x.foo(); // 2 x.bar(); // 3 x.baz(); // 4 x.qux(); // 5 } // specialization 3, IFNDR template<> void X<int>::qux() { std::cout << "qux spec"; } 0) к моменту компиляции main() компилятору известно следующее: определение шаблона класса A с определением всех членов, и declared specializations A<int>::foo() и A<int>::bar(), которые являются определяющими объявлениями (basic#def-2) 1) в точке 1 требуется определение специализации X<int>. в явном виде эта специализация ни объявлена, ни определена, поэтому определение генерируется согласно temp.spec#temp.inst-2 и следующего за ним пункта 3: template<> class X<int> { // declaration from spec 1 void foo(); // declaration from spec 2 void bar(); // 3.1, declaration void baz(); // 3.2, (deleted) definition void qux() = delete; }; зато в точке 1 компилятор знает о существовании специализаций 1 и 2 (их объявления требует temp.spec#temp.expl.spec-7.sentence-1), и использует их объявления в специализации класса. temp.spec#temp.inst-3 для них не работает ввиду temp.spec#temp.inst-11.sentence-1 (*) 2) в точке 2 нужно сначала разрешить перегрузку. множество кандидатов состоит из одного-единственного объявления X<int>::foo() в X<int>. выбор очевиден, полагаю. 3) после разрешения перегрузки требуется определение специализации X<int>::foo(). известно, что эта декларация пришла из declared specialization, поэтому определение берется оттуда. 4) с x.bar() ситуация полностью аналогична x.foo(), несмотря на то, что в шаблоне класса она является удаленной функцией. 5) в точке 4 про X<int>::baz() известно только объявление. так как оно было неявно сгенерировано в отсутствие declared specialization, то и определение будет неявно сгенерировано согласно temp.spec#temp.inst-4 6) в точке 5 про специализацию 3 ничего не известно, что нарушает требование, о котором шла речь в первом пункте. в ее отсутствие вызов в этой точке является ill-formed, потому что перегрузка разрешается в удаленную функцию X<int>::qux() = delete 7) на момент, когда о специализации 3 становится известно, определение X<int>::qux() = delete уже сгенерировано (п. 1), поэтому она является переопределением и нарушает ODR (*) вчера я жаловался на то, что не знаю, что такое инстанциация, так вот тут тоже не написано, об объявлениях ли речь или об определениях. наверное, и то том, и о другом. подтверждение, которое полагается на качество реализации в отсутствие альтернатив

Vlad
в первую очередь хочу отметить, что ни раньше, ни ...

Да, почему-то я везде написал о частичных, хотя говорил о полных, моя ошибка :) Спасибо за столь подробный разбор, здесь всё понятно. Но вот насчёт последнего вашего примера и примера из стандарта... Во-первых, я бы не доверял как раз реализациям, поскольку пример из стандарта, помеченный как error, они все скомпилировали. Впрочем, как я понял, это ifndr... Однако там нет причин, чтобы данный пример считался error. По разобранному же понятно, почему нет ошибки с C<void> c; в данном примере, ибо методы просто не инстанцируются за ненадобность. Когда же мы объявляем следующую полную специализацию для int, не для void ведь, у нас нет необходимости, чтобы это определение было доступно в какой-либо точке инстанцирования выше. Следовательно, в стандарте в данном примере ошибка или я опять что-то недопонял?

Liber Azerate
Да, почему-то я везде написал о частичных, хотя го...

1) да, реализации вам ничего не должны, потому что нарушается ODR со всеми вытекающими 2) вот здесь в предпоследней строке кода (A<char>) похожий пример. можно еще и над ним медитировать 3) вернемся к тому примеру из стандарта, который вы не поняли. в объявлении специализации template<> C<int>::g() определение C<int> инстанцируется в процессе поиска имени C<int>::g. я перечитал basic.lookup вдоль и поперек, как и некоторые главы раздела стандарта про шаблоны, но не нашел прямого подтверждения, поэтому довольствуемся quality-of-implementation proof и здравым смыслом, что мы не может найти g в C<int>, если у нас нет последнего 4) в свою очередь неявное инстанцирование C<int> ведет к инстанциации deleted defintion C<int>::g() согласно temp.spec#temp.inst-3.2. таким образом еще до определения явной специализации C<int>::g() возникает неявный deleted definition из шаблона класса 5) фатальная ошибка вчерашнего опуса в том, что я разделил пункты 0 и 1. очень ожидаемо, что тут сказать

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Гайс, вопрос для разносторонее развитых: читаю стрим с юарта, нада выделять с него фреймы с определенной структурой, если ли чо готовое, или долбаться с ринг буффером? нада у...
Vitaly
9
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
длина пакета фиксированная, или меняется?
Okhsunrog
7
Карта сайта