Название: Специализация шаблонного метода Отправлено: Racheengel от Февраль 18, 2016, 16:24 Всем привет,
вот столкнулся со следующей проблемой: есть шаблон типа Код: template <int Size, class Element = double> Естественно, для даблов сравнение будет работать неправильно. Поэтому появилось желание специализироваться, добавив: Код: template <int Size, class Element = double> Но... не компилируется, студия говорит, что "определение уже существует". Подозреваю, что тупой компилятор воспринимает Element по умолчанию как double и генерирует 2 идентичных определения оператора (но с разным телом). Есть ли простые методы борьбы с подобным? Менять сигнатуру шаблона "низя"... Название: Re: Специализация шаблонного метода Отправлено: m_ax от Февраль 18, 2016, 17:07 Лучше вынести операторы сравнения (и вообще подобные бинарные операторы) из класса:
Код
Название: Re: Специализация шаблонного метода Отправлено: Alex Custov от Февраль 18, 2016, 18:15 Я где-то слышал звон, что VC не поддерживает специализацию шаблонов для членов класса.
Название: Re: Специализация шаблонного метода Отправлено: Racheengel от Февраль 18, 2016, 18:59 m_ax, спасибо за идею, но во втором случае ругается на несоответствие количества параметров в сигнатуре шаблона :(
Alex Custov, да не, поддерживать то поддерживает, другой вопрос - КАК... Название: Re: Специализация шаблонного метода Отправлено: m_ax от Февраль 18, 2016, 20:32 Цитировать спасибо за идею, но во втором случае ругается на несоответствие количества параметров в сигнатуре шаблона В смысле не совместимость? А что именно пишет?У меня всё работает.. Название: Re: Специализация шаблонного метода Отправлено: Igors от Февраль 19, 2016, 07:47 Код Ну или через typeid для старых компиляторов. И вообще, не лучше ли так Код
Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 08:05 Ну или через typeid для старых компиляторов. Шаблоны как раз и призваны избавить нас от таких проверок в рантайме.И вообще, не лучше ли так Как? Вначале проверять размер? :)Так ТС его скорее всего проверяет. У него проблема в другом. Название: Re: Специализация шаблонного метода Отправлено: Igors от Февраль 19, 2016, 09:01 Шаблоны как раз и призваны избавить нас от таких проверок в рантайме. А что "такого уж хорошего" в этом избавлении? Расписывать длинные сопли с угребочными именами x и у? Да за одно это уже надо ставить к стенке.Как? Вначале проверять размер? :) Темплейтщина на каждый чих создает новый класс - и это далеко не всегда удобно/выгодно. Чего это я не могу сравнить вектор int c вектором float? Или с вектором std? Такая операция совершенно разумна. Так ТС его скорее всего проверяет. У него проблема в другом. Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 09:18 А что "такого уж хорошего" в этом избавлении? То что не нужно тратить время при исполнении на проверки, которые можно выполнить в компилетайме.Для вас это не важно, но бывают программы не только для секретарш. ;) Расписывать длинные сопли с угребочными именами x и у? Да за одно это уже надо ставить к стенке. Чего? :)Название: Re: Специализация шаблонного метода Отправлено: Igors от Февраль 19, 2016, 10:17 То что не нужно тратить время при исполнении на проверки, которые можно выполнить в компилетайме. Ага, ага. "И чтобы ловить ошибки на этапе компиляции". Эта мысль (сама по себе разумная) особенно часто доводится до полного абсурда. Цель достигается слишком дорогой ценой - раздутием кода на ровном месте. А получившаяся конструкция оказывается негибкой, и при малейшем изменении опять надо чего-то "параметризовать". А раздумья над ошибками компиляции нередко превышают затраты на поиск в runtime...но бывают программы не только для секретарш. ;) Может и бывают - но Вы уж точно не их автор :)Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 10:17 Есть ли простые методы борьбы с подобным? Менять сигнатуру шаблона "низя"... Простых, наверное, нет. С++ не поддерживает частичную специализацию шаблонных функций. Так что вариантов несколько:1. Частично специализировать весь класс целиком 2. Сделать сам оператор шаблонным и полностью специализировать его для float и double и всех возможных значений Size (я полагаю, их немного) 3. Вынести сравнение в отдельный класс-стратегию, и вызывать метод этого класса из оператора. Для выбора стратегии по умолчанию можно использовать std::conditional<std::is_floating_point<...>::value...> 4. Просто поставить условие, как указал Igors. Компилятор уберет ненужную ветку из соответствующей интстанциации как dead code. 5. Еще можно заморочиться со SFINAE и как-то сделать так, чтобы инстанциировалась только одна перегрузка для operator== в зависимости от типа элемента. Название: Re: Специализация шаблонного метода Отправлено: __Heaven__ от Февраль 19, 2016, 10:22 Код
Код
Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 10:29 Ага, ага. "И чтобы ловить ошибки на этапе компиляции". Эта мысль (сама по себе разумная) особенно часто доводится до полного абсурда. Цель достигается слишком дорогой ценой - раздутием кода на ровном месте. А получившаяся конструкция оказывается негибкой, и при малейшем изменении опять надо чего-то "параметризовать". А раздумья над ошибками компиляции нередко превышают затраты на поиск в runtime Это потому что вы не знаете инструмент, которым пытаетесь пользоваться.Может и бывают - но Вы уж точно не их автор :) Так я хотя бы стремлюсь... А вы гомнокодите, знаете это и пытаетесь просто придумать красивую отмазку. :)Название: Re: Специализация шаблонного метода Отправлено: m_ax от Февраль 19, 2016, 10:30 Код Вообще это самая плохая идея.. Она не гибкая, не компил тайм и самое главное, если пользователь захочет использовать свой тип с нетривиальным сравнением, то ему либо придётся запускать свои ручёнки в кишки TVector и писать очередной if else, либо определять свой специализированный оператор сравнения, как я в начале и предлагал. Название: Re: Специализация шаблонного метода Отправлено: Igors от Февраль 19, 2016, 11:55 Вообще это самая плохая идея.. Она не гибкая, не компил тайм и самое главное, если пользователь захочет использовать свой тип с нетривиальным сравнением, то ему либо придётся запускать свои ручёнки в кишки TVector и писать очередной if else, И что? Это дешево, удобно, практично. Нет никаких оснований отказываться от простого кода. Гляньте как в Qt сделано сравнение QVariant либо определять свой специализированный оператор сравнения, как я в начале и предлагал. А так значит "рученки не запускаются"? Вынесли из класса - и якобы это уже "гибкость"? Будет double вместо float или наоборот - и вот уже надо рисовать очередной оператор. "Зато" легко можно не увидеть какого-то внешнего. Хорошо, гибкость так гибкость. Надеюсь Racheengel позволит мне чуть "копнуть". Вот те же флоты потребовалось сравнивать с другими типами (хоть int), и по-разному, напр "точное сравнение", "fuzzy" и с каким-то фиксированным "epsilon". У меня проблем нет - да, подрисовал if/else, добавил GetCompareMode и SetCompareMode - готовченко! А вот что Вы будете делать с тучей операторов? Как обычно ("Вы изменили задачу!", "так Вы определитесь", "пересмотреть архитектуру приложения" и.т.п.)? Или я ошибаюсь? :) Название: Re: Специализация шаблонного метода Отправлено: Racheengel от Февраль 19, 2016, 12:14 Простых, наверное, нет. С++ не поддерживает частичную специализацию шаблонных функций. Так что вариантов несколько: К сожалению, распространенное заблуждение насчет "неподдерживания". Еще хуже, что каждый компилятор заблуждается по разному :) 1. Частично специализировать весь класс целиком Это можно, но тогда придется менять и наследников, а их многовато :( 2. Сделать сам оператор шаблонным и полностью специализировать его для float и double и всех возможных значений Size (я полагаю, их немного) Это не реально - значений может быть много, очень много. 3. Вынести сравнение в отдельный класс-стратегию, и вызывать метод этого класса из оператора. Для выбора стратегии по умолчанию можно использовать std::conditional<std::is_floating_point<...>::value...> Боюсь, не пройдет код-ревью :) 4. Просто поставить условие, как указал Igors. Компилятор уберет ненужную ветку из соответствующей интстанциации как dead code. Идея хорошая - но там та же проблема, что в п. 2... 5. Еще можно заморочиться со SFINAE и как-то сделать так, чтобы инстанциировалась только одна перегрузка для operator== в зависимости от типа элемента. Ну, это будет непереносимо, думаю... Но в любом случае, спасибо за советы) Название: Re: Специализация шаблонного метода Отправлено: Racheengel от Февраль 19, 2016, 12:19 И что? Это дешево, удобно, практично. Нет никаких оснований отказываться от простого кода. Гляньте как в Qt сделано сравнение QVariant "Иногда, когда я смотрю код Qt, мне хочется взять в руки ружье :)" Надеюсь Racheengel позволит мне чуть "копнуть". Вот те же флоты потребовалось сравнивать с другими типами (хоть int), и по-разному, напр "точное сравнение", "fuzzy" и с каким-то фиксированным "epsilon". У меня проблем нет - да, подрисовал if/else, добавил GetCompareMode и SetCompareMode - готовченко! Эх, как-то помнится, была подобная тема, про сравнения :) Имхо лучшим вариантом было бы обязать компилор генерировать правильный код для оператора == в зависимости от операндов. И добавить еще один оператор "побитного" сравнения (это для эстетов) - что-то типа "===" или подобного) чтоб выглядел страшно и сразу бросался в глаза, как что-то не очень хорошее :) Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 12:47 К сожалению, распространенное заблуждение насчет "неподдерживания". Еще хуже, что каждый компилятор заблуждается по разному :) В стандарте этого нет, значит C++ это не поддерживает. Я ничего не говорил про компиляторы - в GCC 4.9, по-моему, есть соответствующий экстеншн, а вот 2013-ая студия ругается.Это можно, но тогда придется менять и наследников, а их многовато :( Зачем? Наследники переопределяют operator==?Это не реально - значений может быть много, очень много. Ну, в таком случае, я думаю, не стоит использовать Size как шаблонный параметр. Code bloat, вот это все.3. Вынести сравнение в отдельный класс-стратегию, и вызывать метод этого класса из оператора. Для выбора стратегии по умолчанию можно использовать std::conditional<std::is_floating_point<...>::value...> Боюсь, не пройдет код-ревью :)4. Просто поставить условие, как указал Igors. Компилятор уберет ненужную ветку из соответствующей интстанциации как dead code. Идея хорошая - но там та же проблема, что в п. 2...5. Еще можно заморочиться со SFINAE и как-то сделать так, чтобы инстанциировалась только одна перегрузка для operator== в зависимости от типа элемента. Ну, это будет непереносимо, думаю...Название: Re: Специализация шаблонного метода Отправлено: Racheengel от Февраль 19, 2016, 13:15 Т.е. у вас предполагается множество разнообразных типов элементов с разнообразной же логикой оператора сравнения, а не только Fuzzy/Direct Comparison? Тогда стратегии, однозначно, хрестоматийный случай. :) Для классов у нас переопределен ==, но для простых типов достаточно будет Fuzzy/Direct Comparison. Ну, вам видней, конечно, но если грамотно все сделать - не вижу никаких проблем, оверхеда нет, модифицировать библиотеку для добавления новых типов элементов не нужно, если нужно расширить стратегию - клиентский код просто специализирует ее для своего типа в своем же коде. Или у вас в гайдлайнах указано "Никаких стратегий, Александреску - враг народа!"? У нас в гайдлайнах написано что-то вроде "Avoid unnecessary overhead" - а Александреску сам по себе ходячий оверхед :) Почему же? Принцип SFINAE как раз является частью стандарта. Хотя, вообще, вы правы - компиляторы понимают его несколько по-разному, но я уверен, что можно будет подобрать некий общий знаменатель, который будет работать на всех требуемых вам платформах. По поводу шаблонов и перегрузок, кстати, понравилась цитата одного товарища с хабры: Цитировать Круто. Но все-же очень жаль, что С++ в какой-то момент стал развиваться в таком извращенном направлении. Теперь это не остановить, и на шаблонах пишут уже почти все что угодно вплоть до нетривиальных вычислений времени компиляции и парсеров. К сожалению. А ведь по сути они задумывались лишь как возможность написания универсальных функций и структур данных, т.е. чтобы не писать например отдельные классы списка для int, float и string. Название: Re: Специализация шаблонного метода Отправлено: ViTech от Февраль 19, 2016, 13:49 Мне вот что интересно: если в этом шаблоне параметр Element по умолчанию равен double, т.е. предполагается, что этот класс чаще всего будет использоваться именно с double, то почему там изначально "неправильное" сравнение для double? И какое "правильное"? По идее вопрос должен быть в другом: "В этом шаблоне какой-то дурак указал параметр по умолчанию double и приделал qFuzzyCompare. Это что, теперь и для целочисленных типов надо qFuzzyCompare использовать? И для других тоже?".
Хотя нормальные вопросы, которыми на мой взгляд стоит задаться, такие: 1. Почему для элементов типа double в этом классе не подходит "общепринятая" операция сравнения? И какая операция сравнения в данном случае (для данного класса) "правильная"? 2. Какими ещё типами может специализироваться шаблон? Какая для них "правильная" операция сравнения? Можно ли из этих вопросов сделать вывод, что для класса TVector используется какая-то особенная именно для него операция сравнения элементов? Может в этом направлении и надо копать? Я бы предложил использовать вариант m_ax, или перегружать отдельную функцию для сравнения элементов вектора (типа qFuzzyCompare), если остальной алгоритм сравнения одинаков. Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 14:10 Для классов у нас переопределен ==, но для простых типов достаточно будет Fuzzy/Direct Comparison. Ну распрекрасно, тогда для способа с ветвлениями в коде - как-то так:Код Работать будет, но расширяемость никакая, если потребуется для какого-то из классов элементов переопределить логику оператора сравнения контейнера, то придется все эти else-if перелопачивать. А вот со стратегиями - запросто - просто специализируете класс стратегии для типа элемента - и вперед. Конечно, в этом случае std::conditional уже не проканает, придется добавить еще класс характеристик элемента, который будет подбирать стратегию, наиболее ему соответствующую. У нас в гайдлайнах написано что-то вроде "Avoid unnecessary overhead" - а Александреску сам по себе ходячий оверхед :) Рантайм оверхед там нулевой, все вызовы методов стратегий инлайнятся. Компиляцию это замедлит, конечно, да и читабельности и понятности кода это добро совсем не добавляет, но тут уж такое дело - шаблоны - штука непростая.По поводу шаблонов и перегрузок, кстати, понравилась цитата одного товарища с хабры: Да ради бога, эта первоначальная функциональность никуда не делась, никто вам не мешает писать обобщенный класс для всех, и специализировать его для float и double, коль скоро вам потребовалась другая логика.Название: Re: Специализация шаблонного метода Отправлено: Racheengel от Февраль 19, 2016, 14:36 Мне вот что интересно: если в этом шаблоне параметр Element по умолчанию равен double, т.е. предполагается, что этот класс чаще всего будет использоваться именно с double, то почему там изначально "неправильное" сравнение для double? И какое "правильное"? По идее вопрос должен быть в другом: "В этом шаблоне какой-то дурак указал параметр по умолчанию double и приделал qFuzzyCompare. Это что, теперь и для целочисленных типов надо qFuzzyCompare использовать? И для других тоже?". Нет, наоборот - по умолчанию для всех типов использовался стандартный ==, так как TVector предназначен для любых типов, как примитивных, так и нет. qFuzzyCompare понадобился потом, для даблов и флотов. 1. Почему для элементов типа double в этом классе не подходит "общепринятая" операция сравнения? И какая операция сравнения в данном случае (для данного класса) "правильная"? http://ru.stackoverflow.com/questions/399420/%D0%91%D0%B5%D0%B7%D0%BE%D0%BF%D0%B0%D1%81%D0%BD%D0%BE-%D0%BB%D0%B8-%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B4%D0%BB%D1%8F-%D1%82%D0%B8%D0%BF%D0%B0-double 2. Какими ещё типами может специализироваться шаблон? Какая для них "правильная" операция сравнения? Пока что интересуют double и float, т.к. для классов обычно оператор сравнения переопределен. Можно ли из этих вопросов сделать вывод, что для класса TVector используется какая-то особенная именно для него операция сравнения элементов? Может в этом направлении и надо копать? Я бы предложил использовать вариант m_ax, или перегружать отдельную функцию для сравнения элементов вектора (типа qFuzzyCompare), если остальной алгоритм сравнения одинаков. Алгоритм простой - сравнивается "каждый с каждым" до первого расхождения. Название: Re: Специализация шаблонного метода Отправлено: Racheengel от Февраль 19, 2016, 14:40 Ну распрекрасно, тогда для способа с ветвлениями в коде - как-то так: Код
Да, походу придется что-то такое и сделать, наверное. Выглядит, конечно, кривенько, но хотя бы ревью пройдет) Рантайм оверхед там нулевой, все вызовы методов стратегий инлайнятся. Компиляцию это замедлит, конечно, да и читабельности и понятности кода это добро совсем не добавляет, но тут уж такое дело - шаблоны - штука непростая. Template cancer :) это не пройдет, т.к - нельзя нарушать принцип KISS. Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 14:54 Да, походу придется что-то такое и сделать, наверное. Выглядит, конечно, кривенько, но хотя бы ревью пройдет) Пожалуй, лучше сделайте как ViTech предложил, через перегрузку: Код
Название: Re: Специализация шаблонного метода Отправлено: ViTech от Февраль 19, 2016, 15:06 Нет, наоборот - по умолчанию для всех типов использовался стандартный ==, так как TVector предназначен для любых типов, как примитивных, так и нет. qFuzzyCompare понадобился потом, для даблов и флотов. ... Пока что интересуют double и float, т.к. для классов обычно оператор сравнения переопределен. Мой основной посыл в том, что по каким-то причинам (вполне рациональным), в классе TVector необходима своя отдельная операция по сравнению элементов, когда нельзя полагаться на "общепринятые" сравнения. Значит надо добавить операцию сравнения элементов именно для этого класса (либо для семейства классов, пространства имён). И пока набрасывал пример кода, kramer опередил и написал именно то, что я и хотел предложить :). В простом случае, если надо обеспечить qFuzzyCompare для вещественных типов, можно обойтись перегрузкой функции. Для более сложных и обобщённых случаев можно шаблонный класс для сравнения завести, и функцию для облегчения доступа к нему. Соответственно "способ с ветвлениями в коде - как-то так:" я бы использовать не стал, kramer объяснил почему, я это поддерживаю. Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 18:21 В связи с отсутствием у меня VC, нашел сайт с возможностью online-компиляции: http://webcompiler.cloudapp.net/
Там для компиляции используется Visual C++ версии: Compiler version: 19.00.23720.0 (x86). Last updated: Jan 20, 2016 Следующий код спокойно собирается: Код
Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 20:20 Там для компиляции используется Visual C++ версии: Ну, не всем же так повезло, что есть возможность использовать распоследние версии компиляторов. Я, например, на VS 2012 (это 17.0) только в прошлом году перешел, а до того сидел на 2008-ой. И под линуксом тоже - GCC 4.1 за радость.Compiler version: 19.00.23720.0 (x86). Last updated: Jan 20, 2016 Следующий код спокойно собирается: ==dork mode on== И все равно, это не С++. Это расширение компилятора, тем более майкрософтовское. Без ключа /Za что-нибудь кросс-платформенное писать - это танцы на граблях. ==dork mode off== Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 20:26 Без ключа /Za что-нибудь кросс-платформенное писать - это танцы на граблях. Добавил этот флаг на сайте - все равно собирается (не считает vc это расширением). :)А то что он это не собирал раньше говорит только о его убогость. :) Мне лень сейчас ковыряться в стандарте, но... в C++ нет частичной специализации функций, потому что есть возможность их перепределять. Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 21:10 Добавил этот флаг на сайте - все равно собирается (не считает vc это расширением). :) Так-то оно так, но это не отменяет необходимости использовать этот старый, убогий компилятор. У топикстартера последнего нет, а тот, что у него есть, частичную специализацию не поддерживает. А то что он это не собирал раньше говорит только о его убогость. :) Мне лень сейчас ковыряться в стандарте, но... в C++ нет частичной специализации функций, потому что есть возможность их перепределять. Совершенно верно, и, как мне кажется, совершенно оправданно. Усложнять и без того супермозговзрывающие правила перегрузки функций еще и частично специализированными функциями - по-моему, это перебор. Впрочем, это уже оффтопик.Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 21:13 Совершенно верно, и, как мне кажется, совершенно оправданно. Усложнять и без того супермозговзрывающие правила перегрузки функций еще и частично специализированными функциями - по-моему, это перебор. Впрочем, это уже оффтопик. Мне кажется в нашем случае перегрузка и срабатывает, а не частичная специализация.Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 21:21 Мне кажется в нашем случае перегрузка и срабатывает, а не частичная специализация. Вот это: Код есть частичная специализация. Полная была бы Код
VS2013 ваш код не соберет. Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 21:26 Для функций это
TVector<Size, T> и TVector<Size, double> может считаться разными типами. Поэтому происходит обычная перегрузка и никаких частичных специализаций. А VC2013 может еще много чего не собирать. Это пусть его пользователи беспокоятся. :) К тому же, напомню, последний VC не считает это расширением. Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 21:35 Для функций это Компилятор топикстартера это тоже не соберет. См. ответы за номером два и три, в этой ветке.А VC2013 может еще много чего не собирать. Это пусть его пользователи беспокоятся. :) Предложение сменить компилятор (операционную систему, архитектуру, планету, физику) я полагаю флудом. Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 21:37 Компилятор топикстартера это тоже не соберет. См. ответы за номером два и три, в этой ветке. А я сейчас больше не про компиляторы, а про C++.Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 21:48 А я сейчас больше не про компиляторы, а про C++. Частичная специализация шаблонных функций отсутствует в стандарте, а в вашем коде присутствует. То что вы делаете над бедным оператором == и называется частичной специализацией. Как выглядит полная, я написал выше, а уж коль скоро вы один параметр оставляете шаблонным - она частичная. Так что, это не С++.Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 21:54 Если у функции разные параметры это перегрузка. Значит это С++.
Компиляторы, уже даже самый тормозной vc, не считают это расширением, значит это С++. Но спорить больше не буду, если все компиляторы и так это поддерживают, то не имеет значение как это называется. Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 21:59 Если у функции разные параметры это перегрузка. Значит это С++. Перегрузка функций присутствовала в С++ с самого начала. А в вашем коде помимо нее есть еще и частичная специализация. А значит, ваш код - не на С++, потому как частичная специализация шаблонных функций не входит в стандарт. Избавьтесь от нее - тогда будет C++.Компиляторы, уже даже самый тормозной vc, не считают это расширением, значит это С++. Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 22:00 Перегрузка функций присутствовала в С++ с самого начала. А в вашем коде помимо нее есть еще и частичная специализация. А значит, ваш код - не на С++, потому как частичная специализация шаблонных функций не входит в стандарт. Избавьтесь от нее - тогда будет C++. Не может там быть перегрузки и частичной специализации одновременно.Но спорить больше не буду, если все компиляторы и так это поддерживают, то не имеет значение как это называется. Уже стандарт.Название: Re: Специализация шаблонного метода Отправлено: m_ax от Февраль 19, 2016, 22:03 Ну уж частичная специализация для класса точно будет везде работать)
Код
И то, что привёл old - это не частичная специализация, а скорее перегрузка. Частичная специализация функции выглядела бы как то так Код Но стандарт для функций это не поддерживает, как известно) Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 22:07 И то, что привёл old - это не частичная специализация, а скорее перегрузка. Справедливости ради, это вы предложили данное решение. Я лишь решил проверить его на убогом VC и как оказалось они наконец его починили. :)Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 22:08 Но спорить больше не буду, если все компиляторы и так это поддерживают, то не имеет значение как это называется. Безусловно, не имеет. Только компилятор топикстартера это не поддерживает, т.е. в данном топике, я так полагаю, это имеет значение.Уже стандарт. Цитату, будьте любезны. Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 22:11 Цитату, будьте любезны. По праву большинства. Стандарт это договоренность между разработчиками компиляторов и если все из них что-то реализуют одинаково, то совершенно не важно написано это где-то или нет.Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 22:18 Ну уж частичная специализация для класса точно будет везде работать) Это мне больше нравится, чем решение ViTech.Опять же как там vc с этим справится... :) Название: Re: Специализация шаблонного метода Отправлено: m_ax от Февраль 19, 2016, 22:24 Цитировать Опять же как там vc с этим справится.. От этого, самого строгого, всемо можно ожидать) Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 22:24 Справедливости ради, это вы предложили данное решение. Я лишь решил проверить его на убогом VC и как оказалось они наконец его починили. :) Нет, не надо ля-ля. Мое решение не использует частичную специализацию, да и специализацию вообще. Кроме того, это не мое решение, а пользователя ViTech, я всего лишь код накидал.Кроме прочего, насчет убогости VC я с вами согласен. Недавно ужасно глупый баг в VC2012 нашел. Но тут такое дело - плюешься, но надо. Компиляторы на переправе не меняют. По праву большинства. Стандарт это договоренность между разработчиками компиляторов и если все из них что-то реализуют одинаково, то совершенно не важно написано это где-то или нет. Стандарт - это документ. Страниц на семьсот. В последнем принятом c++14 нет ни слова о частичной специализации шаблонных функций.Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 22:29 Нет, не надо ля-ля. Смотрите кому я отвечаю.Стандарт - это документ. Страниц на семьсот. В последнем принятом c++14 нет ни слова о частичной специализации шаблонных функций. Да хоть на 100500. :)Даже если эти слова появяться, то они будут просто словами, пока это не реализуют в компиляторах и наоборот. И в нашем случае нет частичной специализации шаблонных функций, а есть перегрузка. Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 22:39 Смотрите кому я отвечаю. Оба-на, прошу прощения, недосмотрел.И в нашем случае нет частичной специализации шаблонных функций, а есть перегрузка. Есть. В нашем случае (т.е. в вашем коде) там есть и то и другое. Потому как переменное число шаблонных параметров у оператора сравнения. Это и есть частичная специализация, по определению. Полная - это template<>.Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 22:42 Есть. В нашем случае (т.е. в вашем коде) там есть и то и другое. Потому как переменное число шаблонных параметров у оператора сравнения. Это и есть частичная специализация, по определению. Полная - это template<>. Это две совершенно разных функции с совершенно разными параметрами, не нужно проводить параллели с классами, их там по стандарту нет.Спорить надоело, поэтому еще раз вернусь к разработчикам компиляторов: они все как один не считают это расширением. Если это не расширение, то это стандарт, если это стандарт, то это не частичная специализация. Название: Re: Специализация шаблонного метода Отправлено: Racheengel от Февраль 19, 2016, 22:46 О, сколько нафлудили :)
Спасибо всем откликнувшимся за пред ложенные решения :) Проблему в итоге решили в классе наследнике от TVector, который его специализировал. И да, тупая древняя 2008 студия много чего не так понимает... Что касается стандарта - считаю его во многих случаях уделом теоретиков. Реальный код все равно в итоге собирается конкретными компиляторами, и нам намного важнее то, как ту или иную вещь понимает отдельно взятый компиль и какой код генерирует по факту. А стандарт имхо сродни такому себе Hoch Deutsch - немецкий язык вроде как один, стандартный, да только в каждой земле все равно говорят по своему :) Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 22:54 И да, тупая древняя 2008 студия много чего не так понимает... Ох. Товарищ по несчастью. Сочувствую. Я с нее на 2012 только недавно перелез.А стандарт имхо сродни такому себе Hoch Deutsch - немецкий язык вроде как один, стандартный, да только в каждой земле все равно говорят по своему :) Вот-вот. Поэтому, если вы хотите, чтобы вас поняли в любой земле, вы говорите на hochdeutsch, его вроде как в школе учат. Вы, помнится, что-то про переносимость говорили. Название: Re: Специализация шаблонного метода Отправлено: Old от Февраль 19, 2016, 23:00 Вы, помнится, что-то про переносимость говорили. Вот об это и речь. Стандарт есть, а переносимости все так и нет. :)Название: Re: Специализация шаблонного метода Отправлено: Racheengel от Февраль 19, 2016, 23:17 Ох. Товарищ по несчастью. Сочувствую. Я с нее на 2012 только недавно перелез. Да сама то по себе 2008 студия как ИДЕ нормальная, мы ее для кодописания только и юзаем. Пробовали ИДЕ от 2013 - оказалось еще тем оцтоем. Реально используем компилятор от 2013 (а собираем через Qt креатор, т.к. проекты от 2008 студии она толком не может сконвертировать). Компиль классный в плане производительности - 20-25% прироста дает только так. Но есть и старые машины (у заказчиков), которым приходится собирать в 2008 :( Плюс под линухи у нас GCC и CLang, а это еще те ребята :) Студия по сравнению с ними еще более-менее толерантна к коду. Вот-вот. Поэтому, если вы хотите, чтобы вас поняли в любой земле, вы говорите на hochdeutsch, его вроде как в школе учат. Вы, помнится, что-то про переносимость говорили. Проблема только в том, что производители компиляторов трактуют стандарт по своему, так что переносимости как раз не получается :( Название: Re: Специализация шаблонного метода Отправлено: kramer от Февраль 19, 2016, 23:47 Проблема только в том, что производители компиляторов трактуют стандарт по своему, так что переносимости как раз не получается :( Вот об это и речь. Стандарт есть, а переносимости все так и нет. :) Есть она, есть. Не стопроцентная, конечно, от некоторых ифдефов никуда не денешься. Но если вы не буст пишете, то вполне можно свести их количество к минимуму. Лично мне правило "если этого нет в стандарте, вероятны грабли с переносимостью" сэкономило немало крови. Просто потому, что если что-то есть в стандарте, вероятность того, что оно будет работать одинаково на разных платформах несколько выше, чем если этого в стандарте нет. Истина выстраданная :)Название: Re: Специализация шаблонного метода Отправлено: Igors от Февраль 20, 2016, 11:26 Ну распрекрасно, тогда для способа с ветвлениями в коде - как-то так: ... Работать будет, но расширяемость никакая, если потребуется для какого-то из классов элементов переопределить логику оператора сравнения контейнера, то придется все эти else-if перелопачивать. Да, походу придется что-то такое и сделать, наверное. Выглядит, конечно, кривенько, но хотя бы ревью пройдет) А чего это мы "носик воротим"? :) Полагаю что главное (если вообще не единственное) соображение типа "ну это слишком просто, незатейливо" - и только :) Ну какие "перелопачивания", откуда они возьмутся? Совать сюда сравнение объектов никто не собирался, они должны иметь оператор ==. А остальное ложится прекрасноА вообще использование fuzzy в операторе == считаю неудачной идеей. Это "implicit" действие, за которое придется расплачиваться. Напр 2 контейнера float оказались равны. Но их double копии - уже НЕ равны. Лучше сделать fuzzy сравнение явным (explicit) добавив метод CompareFuzzy. Или, если этот класс в недрах др темплейтов, сделать специализацию всего класса <> и подчеркнуть это Fuzzy в его имени. |