LINUX.ORG.RU

Re: C++ частичная специализация шаблонов функций есть!!!

Это называется перегрузкой Ж))) Частичной специализации generic методов, и функций по прежнему нет :)

aton ()
Ответ на: Re: от AIv

Re:

> Э... а что ты тогда называешь частичной специализацией?

afaiu разница вот такая: представь себе что ты где то в другом месте пишешь какой-то шаблон. Там у тебя есть какие-то типы-параметры шаблона. И теперь ты по этим типам хочешь взять адрес функции-шаблона (той функции которую ты хотел специализировать). И тут у тебя облом -- частичной специализации нет.

То есть если тебе нужно сделать просто вызов функции, то перегрузка нормально сработает. В более сложных ситуациях перегрузка не поможет. ИМХО.

dilmah ★★★★★ ()
Ответ на: Re: от dilmah

Re:

Мне сейчас неск впадлу смотреть литературу, но как то наивно всегда думал что это и есть частичная специализация... когда ты для некоторых из параметров задаешь другое поведение. Моно это конечно и перегрузкой называть.... ето разве в данном случае не синонимы?

ПРо адрес шаблона без парамтров - увы да... это местами очень сильно ограничивает. Но вообще то лечиться дополнительной параметризацией по конст инту... некрасиво, но работает.

Вообще С++ конечно ограничен... и шаблоны в нек-м смысле костыли. Но при всем богатсве выбора... опять щас флейм за языки пойдет;-)

AIv ★★★★★ ()
Ответ на: Re: от AIv

Re:

нет не синоним, и ни имеет ничего общего

z<char*, int>("zzz",1);
z<char*>("zzz",1);

С случае частичной специализации можно было бы предположить
такой вывод:

1
1

в действительности:

1
0

> Вообще С++ конечно ограничен...
Это твои познания в C++ ограничены

> и шаблоны в нек-м смысле костыли
Это одна из основных парадигм языка


aton ()
Ответ на: Re: от aton

Re:

Да, ступил чуть - аффтору надо было писать

template<class T> z<T,int>()...

вот это частичная специализация (ИМНО), и это работает. А в примере была перегрузка... никогда так не пробовал перегружать.

> и шаблоны в нек-м смысле костыли Это одна из основных парадигм языка

одно другого не исключает. Есть языки где шаблоны присутствуют изначально, в С++ терминологии... oCaml напр, наск я про него смотрел. Причем гораздо бол. гибко все, и при этом хорошо типизировано.

> Вообще С++ конечно ограничен... Это твои познания в C++ ограничены

А вот хамить не надо. Судя по твоим постам, ты до гуру еще не дорос... Я пока еще от тебя особо дельных постов не видел. А вот с дискуссии ты сливаешь на 3-15, как только прижмут... И не тебе, typedef-о-фил, о моих познаниях в С++ судить...

AIv ★★★★★ ()
Ответ на: Re: от aton

Re:

> Это одна из основных парадигм языка

Сам си++ костыль для си, а шаблоны в этом языке еще больший кривой костыль, чем все остальное вместе взятое. Косвенных улик, подтверждающих мои слова уйма.

BottleHunter ()
Ответ на: Re: от AIv

Re:

> Да, ступил чуть - аффтору надо было писать
> template<class T> z<T,int>()...

Это ты опять тупиш да? Частичной специализации методов/функций не бывает!!!

> вот это частичная специализация (ИМНО), и это работает.
Гонишь

> Есть языки где шаблоны присутствуют изначально, в С++ терминологии... > oCaml напр, наск я про него смотрел. Причем гораздо бол. гибко все, и > при этом хорошо типизировано.

Ты еще много не видил и не знаеш, и не можеш так вольно рассуждать на
тему гибкости и типобезопасноти шаблонов в С++, твои рассуждения заведомо будут неверны.




aton ()
Ответ на: Re: от BottleHunter

Re:


> Сам си++ костыль для си, а шаблоны в этом языке еще больший кривой
костыль

С точностью наоборот, если бы не совместимость с С, язык был бы более
понятен и очевиден

> Косвенных улик, подтверждающих мои слова уйм
Можно хоть одно подтверждение.

aton ()
Ответ на: Re: от aton

Re:

>Это ты опять тупиш да? Частичной специализации методов/функций не бывает!!!

да, туплю... ептить! Во дела... я всю жизнь для классов част.специализацию юзал, а для функц. действит только перегрузка. И нафуя так?

И тем не менее - ПОВЕЖЛИВЕЕ, тезка. Вот когда выйдет книга "Язык D++. Антон Калинин." - тогда можешь начнать хамить, мля.. и то не факт. А про то что я видел, а чего не видел - опять таки, ты-то этого точно не знаешь. И про ограниченность и кривизну С++ я могу говорить достаточно вольно, хотя и не писал на нем активно уже пару лет - достаточно того, что этот язык не дает мне делать то что мне надо, хотя это вполне типизированно. Но за языки флеймить мне чесно гря времени жалко...

AIv ★★★★★ ()
Ответ на: Re: от AIv

Re:

> И про ограниченность и кривизну С++ я могу говорить достаточно вольно, > хотя и не писал на нем активно уже пару лет - достаточно того, что
> этот язык не дает мне делать то что мне надо, хотя это вполне
> типизированно

Если не влом конкретизируй проблему

aton ()
Ответ на: Re: от aton

Re:

Да их тьма... напр - невозможность передавать шаблонный класс (функцию) в шаблонную же функцию без параметров.

template <int I> A...; template <int I> B...;

template <class T, int I> reduce(){ ... T<I>= ...}

Хочу reduce<A, I>... - хера.

приходиться

enum EC{A,B,...};

template<int iC, int I> class C;

template<int I> C<A,I>{}; ...

Ну и не только.

AIv ★★★★★ ()
Ответ на: Re: от AIv

Re:

> напр - невозможность передавать шаблонный класс (функцию) в
> шаблонную же функцию без параметров

Я бы не был таким голословным :) Опять налицо пробелы в образовании ;)

Вуаля:

template <int I> class A{};
template <int I> class B{};

template <template <int I> class T, int I>
void reduce()
{
T<I> t;
}

int main()
{
reduce<A, 10>();
reduce<B, 11>();
}

Еще что?

aton ()
Ответ на: Re: от aton

Re:

Не знал, проверю. Спасибо:-)

Вложенные шаблоны?

template<class T1> class C{

template<class T2> ...

};

? раньше это не поддерживалось (нау ровне компилятора по крайней мере, что там в спец. языка не помню).

template<class T1, class T2> С не принимается по соображениям синтаксиса в первую очередь... и вообще к синтаксису большиие претензии, ограничивает оч. сильно. Напр, есть произвольная структура

struct P{ double x,y,..;};

Как некторой библиотечной функции объяснить, какое поле этой структуры она должна обратбатывать? Приходиться испольpоват номер (смещение):

template<class T> union U{ T a; double X[sizeof(T)/sizeof(double)]; };

template <class T, int I> void func(T& p){ U<T> t; t.a=p; .... t.X[I] ... } ....

func<P,0>(p) - работаем с P.x

AIv ★★★★★ ()
Ответ на: Re: от AIv

Re:

но вариант со смещением много чем плох... не говоря о том что приходиться считать на каком месте находиться поле (легко ошибиться), так еще и работает это только для однородных по типах структур (напр все далы... или все флоты... или инты). Можно конечно ввести enum EP{x,y,z..}, но опять таки, получается что код дублируется (хи-хи не надо, в нек-х задачах алфавита моежет не хватить:-)).

AIv ★★★★★ ()
Ответ на: Re: от AIv

Re:

По первому пункту...

Раньше это сколько лет назад, и каким компилятором?

--- [CUT HERE] ---
template<class T1> class A {
public:
template<class T2> class Sub {};
};

int main()
{
A<int>::Sub<float> sub_a;
}
--- [CUT HERE] ---

По поводу второго...

> Как некторой библиотечной функции объяснить, какое поле этой
> структуры она должна обратбатывать?

А в чем проблема то собственно:

--- [CUT HERE] ---
struct P
{
double a, b;
};

void func(double f)
{
// что то делаем с f
}

int main()
{
func(P().a);
func(P().b);
}
--- [CUT HERE] ---


aton ()
Ответ на: Re: от AIv

Re:

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

aton ()
Ответ на: Re: от aton

Re:

Ну, если поля double то не сделает. По крайней мере это легко отслеживается. Что касается f(double&) не прокатывает никак. Еще раз - есть структура (напр описывающая характеристику уравненимя, читай нек-ю частицу, число полей - размерность задачи). Есть алгоритм (несколько алгоритмов) моделирования, но нужно задать коээфициенты уравнения - то есть каждому полю структуры сопоставить нек-ю функцию, принимающую эту структуру и еще ряд данных, и сообщить алгоритму что это за функция.

Ну вот, для левой части уравнения я перегружаю метод (или частично специфицирую класс - как хошь).

double left<P,0>::calc(P& p){ return p.Vx; } например (на самом деле все неск сложнее). То есть dx/dt = Vx. но, блин, номера полей - это плохо. Это неудобно. Не говоря уже про проблемы с оптимизацией...

AIv ★★★★★ ()
Ответ на: Re: от AIv

Re:

Раньше - это лет семь назад, 4-й(? или 1-й... не помню) Билдер. Года три назад gcc каким то пробовал - тоже не задалося...

AIv ★★★★★ ()
Ответ на: Re: от AIv

Re:

Еще бы :) 7 лет назад только стандарт принят был

aton ()
Ответ на: Re: от AIv

Re:

> template<class T> union U{ T a; double X[sizeof(T)/sizeof(double)]; };

>template <class T, int I> void func(T& p){ U<T> t; t.a=p; .... t.X[I] ... } ....

>func<P,0>(p) - работаем с P.x

вот это не только implementation-dependent, но, на самом деле - undefined behaviour.

объяснить функции какие поля обрабатывать - стандартный способ - traits

AnToXa ()
Ответ на: Re: от AIv

Re:

> Года три назад gcc каким то пробовал - тоже не задалося...

gcc до 3 версии - вообще убожество.

AnToXa ()

Re: C++ частичная специализация шаблонов функций есть!!!

Подведем итог....


НЕ ЗНАЯ __БРОДУ__ НЕ ЛЕЗЬ В ВОДУ!!!

aton ()
Ответ на: Re: от AnToXa

А это то-же перегрузка?

bash-2.05b$ cat test1.cpp
#include <iostream>
using namespace std;
template<class R, class A>
void z()
{
  cerr << "0" << endl;
  return;
};
template<class R,int A>
void z()
{
  cerr << "1 "<<endl;
  return;
};
main()
{
    z<char*,10>();
    z<int,char*>();
}
bash-2.05b$ g++ test1.cpp
bash-2.05b$ ./a.out
1
0
bash-2.05b$

anonymous ()
Ответ на: Re: от AnToXa

Re:

>объяснить функции какие поля обрабатывать - стандартный способ - traits

а подробнее? пожалуйста... с примером если нетрудно...

2aton - про брод и воду, ты таки ГОНИШЬ... тем не менее за некоторую полезную информацию спасибо.

AIv ★★★★★ ()
Ответ на: А это то-же перегрузка? от anonymous

Re:

для частичной спецификации у тебя число параметров в template<...> должно быть меньше чем число параметров в z<...> - то есть ты в z<...> часть параметров задаешь руками, извне template. Компайлер на это ругается...

AIv ★★★★★ ()
Ответ на: Re: от AIv

Re:

До тебя еще не дошло что нет частичной специализации методов/функций ?!
А в данном случае происходит template OVERLOADING!

aton ()
Ответ на: Re: от aton

Re:

Про traits уже нашел. Не совсем то что нужно - для каждого поля придется писать свой класс...так есть более дешевые вар-ты на основе множественного наследования. Кроме того сложно будет раскручивать рекурсивный обход по координатам (с конст интом это делает легко). В результате либа будет развернута не лицом к пользователям, а задницей... но я подумаю.

Про перегрузку- спецификацию. Я вообще блин догадливый и сообразительный, так что до меня это дошло сразу после того как я попытался компльнуть первый же свой тест. Специально для тебя Б-У-Д-Ь В-Е-Ж-Л-И-В-Е-Е. То что ты чего то знаешь лучше других (м.б.), еще не дает тебе права хамить незнакомымы людям. Если до тебе это до сих пор не дошло - мои исренние соболезнования и нагоняй родителям.

А теперь еще раз внимательно перечитай что я писал.

template< class A, class B> void f<A,B>(){}

template< class A> void f<A>(){}

перегрузка

template< class A, class B> void f<A,B>(){}

template< class A> void f<A,int>(){}

частичн спецификация, для функции будет error: partial specialization `f<T1, int>' of function template

Посчитай число параметров.

AIv ★★★★★ ()
Ответ на: Re: от AIv

Re:

Да ты какой то бред пишешь!!! Так нельзя, ты это сам придумал чтоли?
Хватит запутывать людей!

ЗЫ Я не хамлю, просто ты откровенно тупиш, а я пытаюсь тебе вправить
мозги на место, sorry Ж)

aton ()
Ответ на: Re: от aton

Re:

> С точностью наоборот, если бы не совместимость с С, язык был бы более понятен и очевиден

Хехе. Если бы в Си++ небыло подержки Си, то этот язык назывался бы, например, Object Pascal. Тем не менее называется он Си++.

> Можно хоть одно подтверждение.

Типичный пример кривокостыльности шаблонов - идея разделения интерфейса и реализации на уровне компилируемого модуля. Хорошая понятная идея, которой бог знает сколько лет. В Си и даже в нешаблонном Си++ поддерживается "на ура". Как только дело доходит до шаблонов, идея сдыхает "на корню" Ну трудно сделать норамльные extern template-ы, турдно! Приходится изобретать всякие precompiled header-ы и прочее велосипедство.

Другой пример - ключевое слово typename которое вообще один большой костыль, предназначенный только для того чтобы просто интегрировать механизм шаблонов в обычный Си++.

ну и т.д. Если вспомнить - таких "ляпов" найдется дофига.

BottleHunter ()
Ответ на: Re: от BottleHunter

Re:

> которой бог знает сколько лет. В Си и даже в нешаблонном Си++
> поддерживается "на ура". Как только дело доходит до шаблонов, идея
> сдыхает "на корню"

Конкретизируй, для решения данной проблемы есть немало отличных способов.

>лючевое слово typename которое вообще один большой костыль,

В чем заключается?

>предназначенный только для того чтобы просто интегрировать механизм
>шаблонов в обычный Си++.

Непонятен смысл этой фразы, поясни что это за обычный С++

aton ()
Ответ на: Re: от BottleHunter

Re:

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

aton ()
Ответ на: Re: от BottleHunter

Re:

ключевые слова typename и template(это которое obj.template func<param>(), а не то что вы подумали) введены в язык, чтобы ваш бедненький процессор не перегревался при компиляции простейщего кода - раз. и еще две магических фразы остаются для самостоятельного изучения: export + two phase lookup

AnToXa ()
Ответ на: Re: от AnToXa

Re:

> ключевые слова typename и template(это которое obj.template func(), а не то что вы подумали) введены в язык, чтобы ваш бедненький процессор не перегревался при компиляции простейщего кода -раз.

Первое - мне насрать зачем были введены эти ключевые слова. Если та или иная конструкция языка не решает никакой полезной задачи, а служит только для того чтобы говорить кривому компилятору как правильно парсить мой код, то фтопку такие конгструкции. Язык содержащий такие конструкции как обязательные составляющие следует немедленно признать убогим и кривым. Ч.т.д.

Второе - я конечно видел более или менее нормальные реализации export template-ов, но отнюдь не везде. А gcc это уже поддерживает, и с какой версии ? А visual с++ ? A borland C++ ?

Как я уже говорил эффективно сделать export template реально сложно. Максимум - костыли вроде промежуточного дампа AST на первом проходе компилятора (считай те же precompiled heades), на втором - пытаться разобраться куда какой шаблон следует цеплять, а это отнюдь не просто ибо в Си++ еще есть такая штука как препроцессор. Кстати если ты даже сдампил шаблонное AST, то тебе надо постоянно следить за макроопределениями ибо твое сдампленное AST может быть просто неактуальным при следующей компиляции.

И не надо мне балакать что это есть правильный язык. Си++ это костыль на костыле уже бог знает в каком поколении.

Двухпроходный анализ (если такое уже сделано) тоже не во всех случаях спасет ибо тут на сцене появляется его величество препроцессор. В одном один и тот же

BottleHunter ()
Ответ на: Re: от BottleHunter

Re:

Почти всегда можно будет обойтись без экспортирования шаблонов.

aton ()
Ответ на: Re: от aton

Re:

> Почти всегда можно будет обойтись без экспортирования шаблонов.

Ну прально. Долой нормальное разделение интерфейса и реализации! Каменный век рулит!

BottleHunter ()
Ответ на: Re: от BottleHunter

Re:

>Первое - мне насрать зачем были введены эти ключевые слова. >Если та или иная конструкция языка не решает никакой полезной задачи

полезная задача вам была указана, только вы не читаете. объясняю еще раз, вкратце.

two phase lookup, первая phase - точка определения(definition) шаблона - резолвятся все non-dependent names, вторая phase - точка воплощения(instaniation) - резолвятся все dependent names, т.к. уже известны реальные параметры шаблона.

зачем это нужно: 1. некоторые ошибки можно словить еще при просмотре определения шаблона, в первой фазе. 2. компилятор должен как-то распарсить определение шаблона и понять что же это за штука такая T::type, и если вы не скажете ему, что это есть имя типа (type name), то как компилятор это парсить буддет вообще? 3. вышесказанное особенно важно при наличии export, т.к. у нас нету даже исходника шаблона, то компилятор никак не может определить что же от него хотят, и даже не может сделать AST, потому что не знает чем является какое-то имя.

вот ссылочка еще если интересно: http://www.gotw.ca/gotw/035.htm

и еще маленький ликбез: перепроцессор работает ДО компилятора.

afaik никто не поддерживает template export кроме comeau

AnToXa ()
Ответ на: Re: от AIv

Re:

>для частичной спецификации у тебя число параметров в template<...> должно быть меньше чем число параметров в z<...>

Улыбнуло :)

Открываем TC++PL, параграф 13.5.

template<class T> class Vector {... };

Его частичная специализия:

template<class T> class Vector<T*>: private Vector<void*> { ... }

Думаю, что прав все-таки Страуструп.

devinull ★★ ()
Ответ на: Re: от AnToXa

Re:

> полезная задача вам была указана, только вы не читаете. объясняю еще раз, вкратце.

Т.е. ты хочешь сказать, что костыль для разруливанияконтектсно-зависимости грамматики Си++ является полезной языковой конструкцией ? Да уж ... интересная психология

> 1. некоторые ошибки можно словить еще при просмотре определения шаблона, в первой фазе.

Ага, в основном синтаксические. Бооольшое достижение, ради которого программер вынужден везде писать тупое typename. Я бы сказал это следствие другого глюка - контекстно-зависимости грамматики

> и еще маленький ликбез: перепроцессор работает ДО компилятора.

Спасибо за ценную информацию

BottleHunter ()
Ответ на: Re: от aton

Re:

>>лючевое слово typename которое вообще один большой костыль,

> В чем заключается?

typename - способ разрулить контекстно-зависимость грамматики Си++ приментиельно к шаблонам. Фишка в том что компилятор невсегда на синтаксическом уровне может определить семантику некоторых конструкций. Например, а * b. Как это понимать ? а умножить на b или объявление переменной b которая явл указателем на a ? В обычном нешаблонном си++ разруливалось так же как и в Си. В таблице типов языковых сущностей смотрится что есть 'a', если 'a' - тип данных, то соотв. это декларация переменной, если 'a'- переменная, то все предложение есть выражение языка и т.д. Таких случаев несколько. Применительно к шаблонам так сделать нельзя ибо еще неизвестно что такое 'a'. Раз нельзя так сделать то нельзя и нормально распарсить шаблон, раз нельзя распарсить шаблон, то реализация шаблонов получается не сильно эффективнее макрогенератора. И соотв. ошибки в коде шаблонов выявляются по минимому.

Кстати, например gcc 3.х и borlad C++ builder (на остальных не проверял) вполне нормально хавают априори бредовый код:

template <typename A> class CLS {

int foo() { saldklaskdlasjdkasjfjsrhfjhsadjfhasjhsdjf;}

};

"Умные" дядьки которые придумывают Си++ порешили что это неправильно и ввели в язык конструкцию typename. Костыль чтобы компилятору можно было сказать что является типом, а что нет. В итоге получаем - костыль к апрори кривой синтакскической структуре языка Си++. Спрашивается, нафига ? Нормальный язык контекстно-зависимости допускать просто не должен.

BottleHunter ()
Ответ на: Re: от AnToXa

Re:

> afaik никто не поддерживает template export кроме comeau

Поддерживает EDG-шный фронтенд.

BottleHunter ()
Ответ на: Re: от BottleHunter

Re:

> template <typename A> class CLS {
> int foo() { saldklaskdlasjdkasjfjsrhfjhsadjfhasjhsdjf;}
> };

Так и супер, с точки зрения синтаксиса тут все нормально, проблемы
начнутся в момент инстанционирования, это можно использовать себе
же на руку.

Про typename все что ты сказал абсолютно справедливо, но давай
к этому относится не как к костылю, а как к особенности языка и
закончем флеймить на эту тему, ok?





aton ()
Ответ на: Re: от aton

Re:

> Так и супер, с точки зрения синтаксиса тут все нормально, проблемы начнутся в момент инстанционирования, это можно использовать себе же на руку.

Так тогда лучше использовать просто препроцессор. Зачем такие сложности ? Задача шаблонов - с одной стороны предоставить возможности статического полиморфизма и generic programming-а (или как там это пишется), а с другой - недопустить беспредела как при использовании препроцессора, если они хотябы одну из этих задач не решают - фтопку их. Кстати gcc 4 такой код уже не съест.

> Про typename все что ты сказал абсолютно справедливо, но давай к этому относится не как к костылю, а как к особенности языка и закончем флеймить на эту тему, ok?

Как к этой конструкции относится - вопрос болтологический. Я отношусь к ней как к костылю ибо я вижу те огрехи языкового дизайна которые привели к ее использованию. Никакой полезной семантики в этой конструкции нет. У языка программирования 2 основные задачи: 1) быть интерфейсом между человеком и компьютеров 2) быть интерфейсом между людьми. Излишняя сложность и большой набор чисто языковых условностей мешает выполнять как 1-ю так и 2-ю задачи. Смысл ?

BottleHunter ()
Ответ на: Re: от aton

Re:

2aton

>Да ты какой то бред пишешь!!! Так нельзя, ты это сам придумал чтоли? >Хватит запутывать людей!

Как именнно нельзя? частн. специализацию для ф-й делать нельзя? так я с этим уже давно согласился, удивляет что ты этого до сих пор не заметил:-)

2devinul - можно улыбаться дальше. То что я написал ес-но не является определением... но является достаточным условием. Рекурсию на шаблонных классах параметризованных по инту никогда юзать не приходилось?:-)

AIv ★★★★★ ()
Ответ на: Re: от BottleHunter

Re:

> Так тогда лучше использовать просто препроцессор. Зачем такие
> сложности ?

Дык для generic'a и нужно, тупой но все же пример, в реальных
задачах все по другому:

--- [CUT_HERE] ---
template <class T>
struct fake_type {};

template <class T>
struct foo
{
void bar()
{
fake_type<T>::this_method_is_deprecated_use_foo_bar;
}
void foo_bar() {}
};

int main()
{
foo<int>().bar();
}
--- [CUT_HERE] ---


aton ()
Ответ на: Re: от AIv

Re:

Дайте мне код что-бы компилятор мне ответил
error: partial specialization `f<T1, int>' of function template

anonymous ()
Ответ на: Re: от anonymous

Re:

Это ошибка на уровне семантики, такого сообщения тебе никто не даст,
так как такого понятия в природе просто не существует :)

aton ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.