| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C++ Builder > Поддержка частичной специализации шаблонов |
| Автор: vaddsm 26.5.2009, 02:56 | ||
Подскажите, пожалуйста есть ли возможность сделать на BCB 6.0 подобный код компилируемым:
Или данный компилятор не поддерживает стандарт языка в полной мере? |
| Автор: Lazin 26.5.2009, 08:02 |
| частичная специализация шаблонов применяется в STL, следовательно BCB6 это умеет |
| Автор: vaddsm 26.5.2009, 08:35 |
| Спасибо, что присоединился к данному треду, думал тебя выуживать из общего раздела по c++ .) Касательно проблемы. Совершенно очевидно что -- нет. Предположительно она должна поддерживаться, но видимо не в полной мере. Компилятор не верно парсирует функциональные типы. Приведенный мною код валиден в VC9.0 , Comeau и Mingw но не в Borland (. |
| Автор: Lazin 26.5.2009, 09:00 |
| ну, то что bcb6 не поддерживает стандарт в полной мере - известный факт какой workaround здесь поможет я не знаю |
| Автор: vaddsm 26.5.2009, 09:01 | ||
Еще хочу дополнить пример вот таким фейлом:
+ VC9.0 + Comeau - Mingw - Borland Добавлено через 7 минут и 21 секунду Прошу, взглянуть опытным взглядом и поставить вердикт относительно валидности приведенного кода. Буду очень рад совместимым с другими компиляторами предложениям по изменению кода. |
| Автор: mrbrooks 26.5.2009, 09:34 |
| меня всегда умилял тот факт, что сравнивают CB6 и VC9. |
| Автор: vaddsm 26.5.2009, 09:42 |
| ))) Никто ничего не сравнивает, мне нужно добиться совместимости кода и только. Прошу не разжигать расовой ненависти в этом топике. |
| Автор: azesmcar 26.5.2009, 09:49 | ||||
| vaddsm С точки зрения С++ - нормальный код, с моей точки зрения - выглядет хреново, но это не мешает ему быть правильным. MinGW это откомпилирует по самые помидоры, наверное он на __stdcall ругается. насчет борланда - не знаю, а в чем конкретно проблема и где выдается ошибка? Добавлено через 3 минуты и 18 секунд
речь конкретно об этом куске кода Добавлено через 7 минут и 7 секунд Проверьте этот код.
|
| Автор: vaddsm 26.5.2009, 19:48 | ||
| 2 azesmcar. Ваш пример с небольшой коррекцией
Естественно компилируется всюду. Однако, весьма странно, мой шаблон класса some действительно не компилировался в MinGW по причине указания в шаблоне соглашения __stdcall. Сразу вопрос: почему? И как мне указать соглашение о вызове в шаблоне, для данного компилятора? Добавлено через 6 минут и 58 секунд |
| Автор: azesmcar 26.5.2009, 20:09 | ||
Вообще почему бы не писать так?
|
| Автор: vaddsm 26.5.2009, 20:17 | ||||
Потому как нужен не тип, а адрес метода. Вот, что интересно, в борланде радостно компилируется такой вариант:
А на MinGW, это Segmentation fault. Добавлено через 8 минут и 51 секунду Подитожу:
|
| Автор: vaddsm 26.5.2009, 21:46 | ||||||
Для борланда думаю сделать так:
Да это не частичная специализация, прошу прощение за то что смутил, вот полный вариант с нистид классом где присутствует частичная специализация:
Borland + MinGW -
MinGW + При этом частичная специализация nested проходит в MinGW для всех типов соглашений (не только __cdecl), что весьма странно. |
| Автор: azesmcar 26.5.2009, 21:52 | ||
vaddsm
и все таки я бы сделал так. а какой смысл в этих препроцессорах? На MinGW завтра на работе гляну, дома нет. |
| Автор: vaddsm 26.5.2009, 21:58 | ||
В препроцессорах опечаточка была, подправил.
|
| Автор: azesmcar 26.5.2009, 22:00 | ||
брррр...совсем голова не варит Добавлено @ 22:04 vaddsm Нашел у себя Borland C++ Builder 6.
скомпилировал на ура. |
| Автор: vaddsm 26.5.2009, 22:15 | ||||||
на MingGW, строка 1: parse error before `)' token
Segmentation fault
ok Добавлено через 3 минуты и 45 секунд Причем последняя форма как я уже говорил принимает любое соглашение, и я теряюсь в догадках, каким образом, в таком вот случае, компилятор MinGW знает как именно в nested выполнить такой вот вызов: (A_instanse->*M)(); |
| Автор: azesmcar 26.5.2009, 22:22 |
| vaddsm С Борландом разобрались? |
| Автор: vaddsm 26.5.2009, 22:34 | ||||||
MinGW лол:
Работает )) Да, с борландом все на данный момент ок, в отличие от остальных компиляторов, он требует, указывать конвенцию вызова сразу после типа возвращаемого значения:
при этом typedef указателя на такого рода функцию такой же как и везде:
Не логично, как вы думаете? Добавлено @ 22:36 Спасибо (+1) за ключ к разгадке! Но MinGW меня настораживает и вобще кто из компиляторов прав, я пересмотрел несколько раз стандарт, конкретики в данном вопросе не обнаружил ( |
| Автор: azesmcar 26.5.2009, 22:36 | ||
| vaddsm Скачал MinGW, проверил
работает..в чем проблема то? |
| Автор: vaddsm 26.5.2009, 22:37 |
| Пост выше. Проблема в том что работает ), серьезно. |
| Автор: azesmcar 26.5.2009, 22:40 | ||||
конкретики насчет чего? насчет __stdcall? Там ее и не будет, это Microsoft specific keyword. Добавлено через 3 минуты и 24 секунды А вызов? Обьект класса nested создается? если нет - то все нормально. Пока не используется шаблон - компилятор не генерирует его код. Если да - можно посмотреть как? может быть опять таки - все нормально.
это тоже будет компилироватся - пока класс V не используется |
| Автор: vaddsm 26.5.2009, 22:51 | ||||||
Так. У меня среда Dev. C++ (MinGW компиллер инсайд). На ваш код
ругается матом parse error before `)' token. Только так:
Затем. Я искал в стандарте информацию не о __stdcall в частности а об указании типов конвенций. Добавлено через 2 минуты и 14 секунд В моем примере я вызов делал также
И foo нормально вызывался, хотя не должен бы. |
| Автор: azesmcar 26.5.2009, 22:58 | ||||||
Очень очень странно
вот этот код у меня скомпилировал
может скомпилятором что-то не так, попробуйте вручную, из командной строки.
почему? что ему мешает? попробуйте сгенерировать в уме тот код который сгенерирует компилятор для вашего шаблона, сразу станет понятно почему он работает. |
| Автор: vaddsm 26.5.2009, 23:16 | ||
По вполне, на мой взгляд, понятным причинам. Так как в нутри шаблона необходимо знать не только количество, типы параметров, возвращаяемое значение, но и то каким образом надо работать со стеком. В VS9.0 например такой вот шаблон template <class C, void (C::*M)()> вабще не примет __stdcall метод. Если не указывать явным образом соглашение, должно использоваться соглашение по умолчанию, в борланд в частности для void foo(); это __cdecl. Буду рад оказаться не правым ). В Dev я наблюдаю несколько компиляторов mingw32-gcc.exe и gcc.exe. Сейчас проясню этот вопрос... Добавлено через 10 минут и 16 секунд bin>gcc -dumpversion 3.2 bin>gcc main2.cpp -lstdc++ main2.cpp:76: parse error before `)' token ... bin> |
| Автор: azesmcar 26.5.2009, 23:29 | ||||||
речь идет про __fastcall я так понял? ну тут вы видимо ожидаете рантайм ошибки..так? потому что с точки зрения компилятора - все верно. У него через шаблоны передана функция - он ее вызывает. Единственное в чем он виноват - так в том что не выдал ошибку тут
но... по стандарту - нет ни __fastcall ни __stdcall. Это дополнения - которые к тому же не являются частью сигнатуры функции. Т.е. GCC не обязан проверять это. Тогда вопрос - как же это не вылетает рантайм
предполагаю что в данный момент это было not possible |
| Автор: vaddsm 26.5.2009, 23:29 |
| без __stdcall в шаблоне идет опять таки нормально |
| Автор: azesmcar 26.5.2009, 23:31 | ||
Листинг посмотреть можно? 76 строка, это явно не мой код |
| Автор: vaddsm 26.5.2009, 23:33 |
| ВОТ ВОТ!!!! Я о том и твержу. Access violation быть просто обязан. Указал я __fastcall, чтобы нарочито заставить его обломаться, в том случае если он по умолчанию использует передачу параметров через стек а не регистры. Загадки во тьме..... |
| Автор: azesmcar 26.5.2009, 23:34 | ||
__fastcall 100% гарантии что параметры будут помещены в стек - не дает |
| Автор: vaddsm 26.5.2009, 23:39 | ||||||
тотже:
cmd:
Простите, а что у вас происходит без указания __stdcall в шаблоне, я могу поинтересоваться? Нормально компилируется и так и так?
я целый ряд различных соглашений задавал foo, fastcall часный случай. И все равно работает. |
| Автор: azesmcar 26.5.2009, 23:46 | ||||||||
| vaddsm Чем дальше - тем лучше
кажется вам пора обновляться Добавлено через 2 минуты и 34 секунды
Код который вы мне показали в последнем посте с ошибками
у меня на MinGW прошел без ошибок. |
| Автор: vaddsm 27.5.2009, 00:04 | ||||||
Ну да, почему в разетку пальцем лезть низя он понимает, даже у меня
Понятно, а тот же код но с таким изменением:
Что говорит? |
| Автор: vaddsm 27.5.2009, 00:43 | ||||
И всеже такой формы записи
mingw'у вполне хватает чтобы в шаблоне знать тип соглашения о вызове. Проверил под отладчиком вызов метода foo декларированного с различными соглашениями:
К чему я прихожу: Стандарт не определяет формат описания calling convetions в шаблонах? |
| Автор: azesmcar 27.5.2009, 08:47 | ||||||||||
он вообще не определяет calling convetions. я думаю так: __stdcall чисто микрософтовский кейворд и в GCC это по определению не было. Когда GCC портировали под виндоуз (minGW) __stdcall добавили. Возможно это бага старой версии.
ну мало ли..я думал там вообще с этим неполадки, если тут проверка работает, то почему не работает с шаблонами? мое мнение: Хоть стандарт и не определяет поведение программы в таких случаях - при добавлении новых фич производители компиляторов должы добавить их так - чтобы они соответствовали общей структуре и логике ЯП. В конкретном случае логично то что он не позволяет компилироватся данной программе (у меня).
вот еще вариант с шаблонами.
То что он компилует у вас - видимо просто бага - которую уже давно исправили vaddsm да..и еще..я бы с удовольствием взглянул на ассемблерный код сгенерированный для
особенно интересует вот эта часть.. (a.*M)(1, 2); тут эти два параметра push -ами идут в функцию или mov ecx ..., mov edx? сам не могу..у меня не компилируется |
| Автор: vaddsm 27.5.2009, 09:10 | ||||||||
azesmcar, посмотри внимательнее, приведенный мною asm это как раз то о чем ты меня сейчас просишь, для 3х случаев когда
объявлена как __fastcall, __stdcall и __cdecl. Для случая с __fastcall первый параметр идет в edx, второй в стек.
Да, но я говорю не о частном случае, естественно что описаний самих соглашений в стандарте нет. Меня интересует есть ли в стандарте чтолибо относительно формата указания информации об этих соглашениях в различных синтаксических ситуациях. Добавлено через 1 минуту и 41 секунду упс, прошу прощения за "Ты". Добавлено через 5 минут и 33 секунды
Приведенный вами пример в mingw у меня не компилируется. а вот то что компилится это:
Действительно баг. Добавлено через 6 минут и 48 секунд Радует что в более поздних версиях его выпрямили. |
| Автор: azesmcar 27.5.2009, 09:27 | ||||||
да, ассемблер я увидел, но не совсем понял для какого он кода. Т.е. я думал это для обычного вызова написано а не для вызова через шаблон. следовательно он понимает как ее вызывать ну, что тут скажешь..это компилятор, все в его руках
Добавлено @ 09:28 да без проблем |
| Автор: vaddsm 27.5.2009, 21:30 |
| Для нетипового шаблонного параметра типа указатель на функцию, применяется только “функция к указателю (4.3)” конверсия. Если аргумент шаблона представлен множеством перегруженных функций (или указателем на таковые), то подходящая функция выбирается из множества. Для нетипового шаблонного параметра типа указатель на метод, конверсия не применяется. Если аргумент шаблона представлен множеством перегруженных методов (или указателем на таковые), то подходящий метод выбирается из множества. Конверсия != Конвенция Иными словами в приведенном фрагменте стандарта ничего не говорится о соглашених о вызовах. Добавлено через 8 минут и 18 секунд The C++ Standard [ISO/IEC 14882] has very little to say about calling conventions. It has a bit to say about language linkage and linkage specifications, and it notes that a particular language linkage may be associated with a particular calling convention. Everything else related to calling conventions is implementation specific. Implementation specific для calling conventions, где бы найти |
| Автор: azesmcar 27.5.2009, 21:40 | ||||
не только в приведенном фрагменте. Этот фрагмент касается non-type template-parameter-ов. т.е. это то что в стандарте сказано про передачу шаблонному классу/функции нетипового параметра. Добавлено через 1 минуту и 53 секунды
смотря для кого? если для студии - в MSDN, если для MinGW - то у них на сайте предполагаю что будет. Добавлено через 4 минуты и 43 секунды http://www.hackcraft.net/cpp/MSCallingConventions/ |
| Автор: vaddsm 27.5.2009, 22:00 | ||||
| Тот факт, что стандарт языка не регламентировал «Implementation specific of calling conventions» меня весьма удручает, ну что ж, все же это ответ на вопрос “Почему?”, хоть и отрицательный. На последок хочется взять и кинуть огромным булыжником в огород Borland. Апеллируя к вашим словам “при добавлении новых фич производители компиляторов должы добавить их так - чтобы они соответствовали общей структуре и логике ЯП”, с которыми я чертовски согласен, замечу: Что, разработчики компилятора Borland либо с нами не согласны либо сильно накасячили, заставив пользователей писать:
вместо волне логичного:
|
| Автор: azesmcar 27.5.2009, 22:04 |
| vaddsm надеетесь стать чемпионом по метанию камней в огород борланда? что я говорю...я же в разделе Borland C++ Builder но он в самом деле весьма сомнительно поддерживает стандарт, хотя получше чем Visual Studio 6. Но не будем забывать сколько лет дедушке. |
| Автор: vaddsm 27.5.2009, 22:29 | ||
Heeelp me!!! ) |
| Автор: vaddsm 28.5.2009, 10:34 |
| boost::enable_if так же не работает на 6.0. Вероятно по причине того что принцип substitution-failure-is-not-an-error в компиляторе не реализован (. Придется мне видимо отказаться от некоторых замечательных вещей ради совместимости. Но если вдруг у кого-то будет идея как заставить последний ряд шаблонов работать на этом компиляторе.... Буду ОЧЕНЬ рад. |