Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #60 : 11-04-2009 17:58 » |
|
а ещё один глупый вопрос Скажем, я реализую некую работу с 1) массивом элементов T 2) массивом указателей на элемент T шаблоны вышли одинаковыми, разница лишь T и T* и в доступе к методам элемента: //работа с массивом элементов T template<T> void WorkWithArrayOfT(T* Array, DWORD dwdCount) { ... //доступ к методу T Array[0].Method(); ... }
//работа с массивом указателей на элементы T template<T> void WorkWithArrayOfPointersToT(T** Array, DWORD dwdCount) { ... //доступ к методу T Array[0]->Method(); ... }
то есть к чему я веду ? По сути, если бы не разница в доступе, то строчка WorkWithArrayOfPointersToT<int>(...,...); равносильна WorkWithArrayOfT<int*>(...,...); И вопрос: как в шаблоне сделать условный выбор оператора доступа ? Тогда оба шаблона с практически идентичным кодом можно было бы держать в одном единственном шаблоне
|
|
« Последнее редактирование: 11-04-2009 18:02 от Алексей1153++ »
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #61 : 11-04-2009 18:08 » |
|
Эммм... в самом общем случае никак, и дело не в шаблоне, а в С++. Поэтому и существуют перегруженные конструкторы и ф-ции, которые работают с указателями и с копиями. Посему и с шаблонами ты явно указываешь либо это шаблон для типа, либо на указатель типа.
А зачем тебе это надо?
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #62 : 11-04-2009 18:17 » |
|
и дело не в шаблоне, а в С++.
на ум пришло только такое опасное решение template<T,const bool bPointer> void WorkWithArrayOfT(T* Array, DWORD dwdCount) { ... //доступ к методу T if(!bPointer) { ((T*)&Array[0])->Method(); } else { ((T**)&Array[0])->Method(); } ... }
А зачем тебе это надо?
я же написал зачем - длинный код получился одинаковый, различие только в одной строчке с оператором доступа
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #63 : 11-04-2009 18:48 » |
|
Джон, Cушествует способ. Классика А. Александреску "Современное проектирование на С++" template <typename U> struct PointerTraits { typedef U* ParametrType; }; template <typename U> struct PointerTraits<U*> { typedef U ParametrType; };
template <typename T> class SomeClass { typedef typename PointerTraits<T>::ParametrType PointerType PointerType SomeValue; };
SomeValue всегда будет указателем на данные, вне зависимости, что указали при конкретизации шаблона. Леш, этот пример можно адаптировать под твои нужды.
|
|
« Последнее редактирование: 11-04-2009 18:50 от Finch »
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #64 : 11-04-2009 19:00 » |
|
Finch, как-то это всё сложно для понимания , мозг разбегается )) Что тут чего делает ?
|
|
« Последнее редактирование: 11-04-2009 19:04 от Алексей1153++ »
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #65 : 11-04-2009 19:05 » |
|
Ничего сложного template <typename U> struct PointerTraits { typedef U* ParametrType; };
это обший случай который компилятор обычно будет выбирать, когда будет строить программу. template <typename U> struct PointerTraits<U*> { typedef U ParametrType; };
Это конкретизация для указателя, компилятор ее будет выбирать, если встретит указатель на элемент. Теперь пользуемся этой возможностью typedef typename PointerTraits<T>::ParametrType PointerType PointerType SomeValue;
Более полно и конкретно описано в вышеприведденой книге.
|
|
« Последнее редактирование: 11-04-2009 19:07 от Finch »
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #66 : 11-04-2009 19:11 » |
|
PointerType имеет тип "typename PointerTraits<T>::ParametrType" template<PointerType,const bool bPointer> void WorkWithArrayOfT(PointerType* Array, DWORD dwdCount) { ... //доступ к методу PointerType Array[0]->Method(); }
так ?
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #67 : 11-04-2009 19:14 » |
|
Неа. template<typename T> void WorkWithArrayOfT(PointerType* Array, DWORD dwdCount) { typedef typename PointerTraits<T>::ParametrType PointerType PointerType Array; //доступ к методу PointerType Array[0]->Method(); }
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #68 : 11-04-2009 19:17 » |
|
Вру, сейчас подправлю код.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #69 : 11-04-2009 19:19 » |
|
кстати, на это template <typename U> struct PointerTraits { typedef U* ParametrType; }; template <typename U> struct PointerTraits<U*> { typedef U ParametrType; };
происходит ругань error C2989: 'PointerTraits<class ?? ::U *>' : template class has already been defined as a non-template class error C2988: unrecognizable template declaration/definition
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #70 : 11-04-2009 19:27 » |
|
А ну все, Это вошло в стандарт помоему в 99 году. Так что естественно VC6 показывает язык. У меня на g++ такое проходит и на ура.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #71 : 11-04-2009 19:29 » |
|
понятненько ) Тогда оставлю изврат с bool bPointer
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #72 : 11-04-2009 19:29 » |
|
template<typename ItemType_> void WorkWithArrayOfT(ItemType_* Array, DWORD dwdCount) { ... //доступ к методу T ( (ItemType_*)&Array[0] )->Method(); ... } или нет... И компилятора под рукой нет... Ещё есть идея с порождением вспомогательного объекта с перекрытым оператором -> (типа умных указателей)
|
|
« Последнее редактирование: 11-04-2009 19:31 от Вад »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #73 : 11-04-2009 19:34 » |
|
Вад, агась, я уже так и поступил. Компилятор пропускает (пост #62)
перегружать оператор неохота, если честно
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #74 : 11-04-2009 19:41 » |
|
Лёш, на самом деле всё гораздо проще. Для сокращения кода и существует перегрузка ф-ций: template <class T> void MyFunction(T obj) { ... obj.MyClassMethod(); ... }
template <class T> void MyFunction(T *pObj) { T obj = *pObj; MyFunction(obj); }
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #75 : 11-04-2009 20:28 » |
|
Джон, не могу понять, чем это мне здесь поможет...
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #76 : 11-04-2009 20:33 » |
|
Тем, что ты напишешь тело БОЛЬШОЙ ф-ции только один раз. Чего ты и добивался. А зачем тебе это надо?
я же написал зачем - длинный код получился одинаковый, различие только в одной строчке с оператором доступа зы Ну и ессно тем, что это безопасный код без всяких извращений.
|
|
« Последнее редактирование: 11-04-2009 20:35 от Джон »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #77 : 11-04-2009 20:39 » |
|
Джон, Cушествует способ. Вить, ща только просмотрел твой код, ИМХО это не то, что спрашивалось. Можешь показать пример использования с объектом и с указателем?
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #78 : 11-04-2009 20:43 » |
|
Сейчас помудрю. Кстати, твой код тоже не будет работать У него там не просто один указатель, а массив указателей.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #79 : 11-04-2009 20:52 » |
|
Легко будет работать, надо только определить оператор = для данного типа. Если же передаётся массив указателей, то просто сделать копию с него, размер-то известен.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #80 : 11-04-2009 21:03 » |
|
class MyClass { public:
MyClass() {} void MyClassMethod() { int i=3; printf("Class 1: i=%d\n", i); } };
class MyClass2 { public:
MyClass2() {} void MyClassMethod() { int i=3; printf("Class 2: i=%d\n", i); } };
// основная ф-я с БОЛЬШИМ кодом template <class T> void MyFunction(T *pObj, int nSize) { for(int i=0; i<nSize; i++) { pObj[i].MyClassMethod(); } }
// перегруженая с массивом указателей template <class T> void MyFunction(T **ppObj, int nSize) { T *pObj = new T[nSize]; memcpy(pObj, &ppObj, nSize); MyFunction(pObj, nSize); // вызов БОЛЬШОЙ ф-ции }
int main() { // для массива объектов MyClass2 obj[2]; MyFunction(obj, 2);
// для массива указателей MyClass *pObj[2]; pObj[0] = new MyClass(); pObj[1] = new MyClass();
MyFunction((MyClass*)pObj, 2);
delete pObj[0]; delete pObj[1];
return 0; }
В код внесены изменения для совместимости с 6ой студией. см. ниже
|
|
« Последнее редактирование: 11-04-2009 21:49 от Джон »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #81 : 11-04-2009 21:04 » |
|
Джон, ну покажи пример прямо для поста №1 Может, я просто туплю с недосыпа. Присваивать временной переменной не хочу. Лучше уж с преобразованием из №62 оставлю
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #82 : 11-04-2009 21:06 » |
|
Вот код, который у меня полностью работает. #include <stdio.h>
template <typename U> struct PointerTraits { static void Method(U &u) {u.Method();}; }; template <typename U> struct PointerTraits<U*> { static void Method(U *u) {u->Method();}; };
template <typename T> static void WorkWithArrayOfT(T* Array, int dwdCount) { //доступ к методу PointerType PointerTraits<T>::Method(Array[0]); }
class a { public: a() {}; ~a() {}; void Method() {printf("class a\n");}; };
int main() { a **A=new a*[10]; for (int i =0; i<10; i++) A[i] = new a; WorkWithArrayOfT<a*>(A, 10); a B[10]; WorkWithArrayOfT<a>(B, 10); return 0; }
|
|
« Последнее редактирование: 11-04-2009 21:21 от Finch »
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #83 : 11-04-2009 21:06 » |
|
Лёщ, а это он и есть...
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #84 : 11-04-2009 21:09 » |
|
// это основная ф-я с полностью реализованым телом
//работа с массивом элементов T template<T> void WorkWithArrayOfT(T* Array, DWORD dwdCount) { ... //доступ к методу T Array[0].Method(); ... }
//работа с массивом указателей на элементы T template<T> void WorkWithArrayOfPointersToT(T** ppArray, DWORD dwdCount) { T *pArray = new T[dwdCount]; memcpy(pArray, &ppArray, dwdCount); MyFunction(pArray, dwdCount); // вызов БОЛЬШОЙ ф-ции }
Я только имя переменной изменил немного - терпеть ненавижу когда имя переменной на тим смахивает.
|
|
« Последнее редактирование: 11-04-2009 21:11 от Джон »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #85 : 11-04-2009 21:10 » |
|
Джон у тебя не идет конкретизация шаблона, следовательно ты пример не прогонял через компилятор. Второе, все наши примеры на VC6 скорее всего и не будут работать.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #86 : 11-04-2009 21:12 » |
|
Вить, поскольку я сделал с ф-ей main и примерами классов, то это значит что я прогнал это через компилятор и всё работает. Но твоя правда - я сделал это в 2003 студии. Ща на шестёрке прогоню.
зы Вить, а конкретизация и не требуется. Поэтому я и сказал, что твоё решение не совсем то, что требуется. У Лёшки типичная перегрузка ф-ции с разными параметрами.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #87 : 11-04-2009 21:19 » |
|
Да, в 6ой вторая часть не работает. Не может разрешить перегрузку в случае с массивом указателей.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #88 : 11-04-2009 21:25 » |
|
Да кстати, у тебя зарыта мина замедленного действия . Если в классе будут динамические переменные, могут быть некоторые трудноотлавливаемые баги. Если например приложение многопоточное
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #89 : 11-04-2009 21:29 » |
|
В 6ой версии нужен явный кастинг при вызове
вместо MyFunction(pObj, 2); -> MyFunction((MyClass*)pObj, 2);
Так работает.
|
|
« Последнее редактирование: 11-04-2009 21:50 от Джон »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
|