- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
using System;
public interface IFoo
{
void WhoAmI<T>(T t);
}
public class Foo : IFoo
{
public void WhoAmI<T>(T t)
{
Console.WriteLine(t.GetType().FullName);
}
}
class pituh
{
public static int Main(string[] args)
{
var f = new Foo() as IFoo;
f.WhoAmI("asd");
f.WhoAmI(10);
return 0;
}
}
Иными словами, парочка #if с проверкой на компилятор/окружение должны решить вопрос c кросс-компиляторным demangle. Я почти уверен, что на GitHub (or whatever) уже можно найти рабочий код.
P.S. abi::__cxa_demangle дико бесит, что не constexpr. А ведь тип вполне себе известен на этапе компиляции. Такое ограничение не дает делать constexpr там, где надо получить имя типа...
Оператор, который генерирует литерал по имени типа. Что-то вида typeid.
Скажи это комитету
а ты часом не бароп?
И правильно сделает.
Что бы отменить что то, надо решить что то.
ну так скомпиляйте нам код. а мы посмотрим на него :)
Да, общий случай никто не предскажет и не запилит пацанский пирфоманс. Печально.
Покаж
Ибо генерик вообще не шаблон, это сахарок над Foo<Object>.
В крестах же напротив, шаблонный метод виртуальным не сделать.
раз две принципиально различные вещи для него должны быть сравнимы в категориях лучше-хуже
на балуйся.
ну тогда другой пример - template specialization:
если кококомпилятор c# сохраняет информацию о типах, и сам по себе язык обмазан сахаром в 10 слоев, что им помешало реализовать такую несложную вещь, как частичная/полная специализация?
ну или аналог крестушкового template <int N, int M> class Matrix()
раз уж так хочется сравнить несравнимое
интересно послушать
Если пишет Стертор, то там будет про хуи, педиков, собак, или прочей шизни
Пора бы уже научиться отличать меня.
такой dynamic cast даже в pl/sql есть, прости господи
а можно за O(0) всё таки - компилятор же знает о типе объекта, почему он не выбирает сразу правильную "перегрузку" из набора функций?
или про отсутствие type erasure маркетинговые презентации всё же немного подпёздывают?
в жабе тоже если чего-то нет, оно нахер не нужно
Ты ёбнулся?
там виртуальная функция для особо одаренных стоит что бы компелятор от с++ жидко обгадился когда начнет применять темплейты к фиртуальной функции
> делать не приходиться
> это бред - не говорят не люди не коты.
> что бы компелятор
> там виртуальная функция для особо одаренных стоит что бы компелятор от с++ жидко обгадился когда начнет применять темплейты к фиртуальной функции
Да это же вореционный бот, который своим кобенаторным алгоритмом осознал C++ до возможности написания своего буста, но русский язык учил по комментариям на Ютубе.
Static-C++ style. Ибо нефиг тут динамотой забавляться.
похоже надо самому строить __vtbl и вызывать через номер метода типа __vtbl[0]
А если WhoAmI(const std::type_info&) захочет распечатать само значение, дать ему ссылку на IPrinter, которую создавать в WhoAmI(const T &t), пока тип и значение известны.
https://wandbox.org/permlink/OPyDQMgGd2aKj8K0
там виртуальная функция для особо одаренных стоит что бы компелятор от с++ жидко обгадился когда начнет применять темплейты к фиртуальной функции
Может, специально придумывал искусственную задачу, где C++ напрямую не работает как C#.
а остальное в цппшник. И не надо инстанцировать никакой хуеты
напишите код который будет работать
Да можеш заюзать Boost::any :)
С другой стороны сделать то, что он хочет, довольно просто с помощью паттерна из моего первого примера (aka "curiously recurring template pattern")
Если учесть, что темплейт разворачивается (инстанциируется) только компилятором, и в рантайме инстанциированный темплейт это полноценный обособленный тип (или полноценная обособленная функция), которому в целом поебать, был ли он шаблонным когда-то, и кто его собратья и есть ли они вообще, при этом нет смысла хранить (мета?) код исходного темплейта - рантайму ничего с этим кодом не сделать, он не может и не должен в jit компиляцию какую-то, и новый код из xml или из сети он не сгенерит на лету (и тем более не прооптимизирует, не разберется со SFINAE, не найдет частичные специализации и т.д.) - то виртуальный шаблонный метод это оксюморон. Независимо от стандарта.
Для шарпо(и жабо)ёба интерфейс, походу, единственный контракт, о других они даже не слышали, им сложно принять то, что крестошаблон - это тоже контракт, как и то, что при развертывании кучи вложенных друг в друга шаблонов при обычных условиях компилятор выкинет к хуям информацию о всех промежуточных преобразованиях, получив только высокооптимизированный код, заточенный на конкретный тип.
Буквально недавно я генерил различные многомерные данные (статистика), которые беком должны были обернуться в 0-мерные (значение), 1-мерные (массив), 2-мерные (массив массивов), 3-мерные (...) структуры и отправиться на фронт для визуализации.
Что сделал жавоёб? Один тип для T, второй тип для List<T>, третий тип для List<List<T>>, четвертый для List<List<List<T>>>.
Помогли ему его интерфейсы с виртуальными генериками? Хуй там.
виртуальный означает, что потомок будет переопределять когда-нибудь с тем же контрактом (имя+параметры)
это когда-нибудь может возникнуть в другой длл спустя 10 лет
базовый класс не может предугадать как потомок будет инстанциировать этот метод
что он может сохранить для потомка в данном случае?
только исходный код или AST или ещё какой-нибудь питух-байт-ллвм-код, и в таблице виртуальных методов эти самие питух-коды вообще в отдельные места складывать, т.к. это не исполняемые точки входа
и все потомки, переопределяющие этот шаблон своим таким же шаблоном, должны заменять родительский питух-байткод своим
чтобы когда-нибудь jit компилятор смог в рантайме проинстанциировать эту метушню в валидные исполняемые инструкции
ну или смириться с тем, что <T> это просто сраный сахарок над Object, и контракт этой виртуальной функции именно что принимаем/возвращаем Object, ну или void * - и в этом случае вообще никаких оптимизаций (код предка уже скомпилирован в бинарном виде и неизменяем) и тем более специализаций, максимум, проверки компилятора о типе возвращенного объекта (ещё один сахарок)
Я всё ещё не пойму
Каждый шаблонный метод в крестах раскрывается в свою имплементацию сразу, как только компилятор видит необходимость в этом.
https://wandbox.org/permlink/N9ysRa2YhsT0d2SH
Затем все эти инстанциированные методы лягут в obj файл каждый под своим именем и адресом, чтобы линкер смог их в других модулях подставить в случае нужды.
Нет нужды в инстансе от, например, <char> - никто никакой код не сгенерит, и даже не подумает.
А в пределах единицы компиляции они вообще, скорее всего, заинлайнятся - тебе ведь обычно всё равно, являются ли они обособленными точками входа с каким то колл-конвеншеном, если тебе ни адреса не надо хранить, ничего, главное, чтобы они сделали "при вызове" то, что требуется. При инлайне компилятор их тело встроит в вызываемой код, перетасует, смешает с другими инструкциями, выкинет что-нибудь, и забудет, что это был шаблон какой-то какого-то класса foo, всё как обычно (для шарпера звучит диковато, понимаю).
Что именно ты собрался положить в ТВМ? Исходник шаблонного метода? Я об этом выше написал.
Т.к. спустя 10 лет я пишу свой тип MyAwesomeClass и инстанциирую им эту функцию, написанную кем-то 10 лет назад - какой код должен сгенерить компилятор за 10 лет до того, чтобы так заработало и потомком была найдена точка входа в подпрограмму foo::process<MyAwesomeClass>()?
1) проблема - С++ не разрешает использовать виртуальные темплейтные методы. Почему? потому что компилятор не может предугадать какие параметры темлейты могу быть использованны и поэтому не может сгенерировать __vtbl соответсвенно. А почему он не может это сделать? Ответ: потому что __vtbl распологает методы по порядку 0, 1, 2 в зависимости от того что в декларации класса написанно.
Но все это можно было бы избежать если бы методы в __vtbl референсились не по порядку как в декларации написанно а например по Hash code от имени функции, И тогда больше бы не было проблем с виртуальными темплейтными методами потому что "derived" класс всегда бы знал куда нужно положить метод в виртуальную таблицу.
т.е. не референсить по имени как делают dynamic языки а по hash - и все бы были довольны
virtual void process<int> и virtual void process<double> это две разные подпрограммы.
У них у каждой свои точки входа, у них у каждой свое тело, они даже вправе делать абсолютно своё, независимое друг от друга, и знать друг о друге не хотят.
При этом никакой точки входа у virtual void process<T> нет, т.к. в принципе нет никакого исполняемого кода, который олицетворял собой "неинстанциированный шаблон". Нет никаких машинных инструкций, не сохраняется никакого интермидиед-результата (там компилятор максимум AST может построить в процессе первого этапа разбора, проверить синтаксис - и то старые вижуал студии хуй забивали на двухэтапный разбор шаблона, проверяли только второй этап, в момент подстановки конкретного типа). В единице выполнения (exe, dll) шаблона нет. Есть только инстансы с конкретными типами. Всё. У них нет никакой семейственности. В исполняемой программе в режиме release нет никакого реестра созданных ей типов, ничего такого. Всё байты, даже небо, даже аллах. Исполняемый код - машинные инструкции под конкретную архитектуру/ОС/процессор.
В _vtbl должны лечь указатели на подпрограммы в качестве значения куда делать call/jmp.
Для метода process<T> никакого указателя нет. Для инстансов методов process<int> и process<double> свои указатели. Что класть в __vtbl? Какой из них может переопределить потомок? Что будет, если потомок захочет третий вариант инстанциированного шаблона? Какого объема рантайм нужно притащить в исполняемую единицу, чтобы имея исходный код шаблона (и всего, от чего он зависит) на лету сформировать ещё один метод, не хуже тех двух скомпилированных и прооптимизированных в процессе сборки? Кто будет заниматься поиском адресов функций, которые могут быть вызваны из такого генерирующегося метода в зависимости от текущего Т? А если там тоже шаблонные функции?
http://rextester.com/ZFW58650
вот ближайшая имплементация которая может работать
ну наконец-то, спасибо!
> он не может кастить T в другой тип
Темплейт ничего не кастит.
Он использует переданное точное значение типа вместо Т по всему своему коду для того, чтобы скомпилировать (не исполнить!) самостоятельный тип/функцию/метод, со всеми вытекающими (поэтому будет работать и вызов правильной перегруженной функции, и все остальное. А вот исходного шаблона никакого не останется.
У меня всё.
<a href=" http://cialis10mgprixenpharmacieenligne.com/ ">cialis 10mg prix en pharmacie en ligne </a>
<a href=" http://cialis20mgprixenpharmacierx.com/ ">cialis 20mg prix en pharmacie </a>
<a href=" http://achetercialisenfrancesitefiable.com/ ">acheter cialis generique en france </a>
<a href=" http://achetercialissansordonnanceenpharmacie.c om/ ">vente de cialis sans ordonnance en france </a>
<a href=" http://achatcialisenfrancelivraisonrapide.com ">acheter du cialis en ligne en france </a>
<a href=" http://achatcialis5mgenligne.com/ ">acheter cialis 5mg en ligne en france </a>
<a href=" http://tadalafil20mgpaschereninde.com/ ">tadalafil 20mg pas cher en inde </a>
<a href=" http://achetertadalafilsansordonnance.com/ ">peut on acheter du cialis sans ordonnance en france </a>
<a href=" http://achattadalafilenfranceenpharmacie.com/ ">achat cialis en ligne france </a>
<a href=" http://acheterprednisone20mgenligne.com/ ">acheter prednisone 20 mg en ligne </a>
<a href=" http://acheterpropeciasurinternet.com/ ">acheter propecia sur internet </a>
<a href=" http://achatamoxicillinebiogaran1g.com/ ">acheter amoxicilline 1g en ligne </a>
А если 10 лет назад кто-то скомпилирует указанный ниже класс, у нас при вызове A().method(Class2017()) будут проблемы?
Если будут, то это по сути та же ситуация, но только она допустима в C++, а значит спокойно можно было за счёт знания исходного кода в vtable нагенерить вореций для всех случаев.
Если выносить информацию о типах в рантайм можно вообще много какой метушни натворить. Вот только делать каждый инт наследником Object'а и инстанцировать его в хипе - не самый производительный сценарий, вы не находите?
п.с. именно поэтому студия аж 15 гигов весит (если уже не больше)