Технофашист
228 / 216 / 11
Регистрация: 11.03.2009
Сообщений: 887
1

Шаблоны

25.04.2011, 23:50. Показов 3202. Ответов 23
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Пусть есть шаблон-структура.
C++
1
2
3
4
template <class Data> struct A
{
   Data p;
};
И есть указатели на объекты:
C++
1
2
A<int> *b;
A<float> *c;
Можно ли как-то завести общий указатель для них? т.е. чтоб этот указатель мог указывать и на A<int> и на A<float>?

Пробовал завести родителя (пусть parA) для struct A и создавал указатель этого типа и делал так:
C++
1
2
A<int> *b;
parA * w = b;
Максимум что получилось, это вызвать конструктор через этот указатель:
C++
1
w = new A<int>;
Доступа же к полям не получил. Пробовал явно преобразовывать тип:
C++
1
(A * w).A;
Вылазеет ошибка E2102 Cannot use template 'A<Data>' without specifying specialization parameters
Пробовал сделать родительский класс parA виртуальным и далее через виртуальные методы. Компилятор проглатывает, но ошибка уже на этапе выполнения (ошибка доступа к памяти).

Как быть?


p.s. нужно реализовать стек, элементы которого имеют поля разного типа, а union не охота использовать.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.04.2011, 23:50
Ответы с готовыми решениями:

«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами».
«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами». Есть ли разница в этих понятиях? Если...

Шаблоны. Плохо понимаемые моменты из книги "Шаблоны С++. Справочник разработчика". (Вандевурд, Джосаттис)
Так как изучаю эту книгу, то в некоторых местах возникают вопросы. Чтобы не плодить много тем,...

Помогите писать на С++ через шаблоны. Консуле я писал, но надо писать исползуя шаблоны
В одномерном массиве, состоящем из п вещественных элементов, вычислить: 1) количество элементов...

Шаблоны
Добрый день. Не могли бы объяснить вот этот вопрос: Допускают ли шаблоны вложенность описания?

23
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
26.04.2011, 00:00 2
darkAngel, boost::any))
1
Технофашист
228 / 216 / 11
Регистрация: 11.03.2009
Сообщений: 887
26.04.2011, 15:08  [ТС] 3
не доверяю я STL.
Сделал стек из union.
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
26.04.2011, 16:07 4
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от darkAngel Посмотреть сообщение
не доверяю я STL
*саркастично* Молодец.

boost::any это не STL, это boost. Но ему тоже доверять не надо, ага.

Цитата Сообщение от darkAngel Посмотреть сообщение
Сделал стек из union.
*ещё более саркастично* Молодец.
3
Технофашист
228 / 216 / 11
Регистрация: 11.03.2009
Сообщений: 887
26.04.2011, 16:39  [ТС] 5
Евгений Ваганыч?
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
27.04.2011, 00:06 6
darkAngel, не доверять библиотекам, написанным профессионалами по С++ - глупо.
0
Технофашист
228 / 216 / 11
Регистрация: 11.03.2009
Сообщений: 887
27.04.2011, 00:41  [ТС] 7
дело в перегрузке функционала + могут понадобиться нестандартные функции + свои структуры данных я могу подстраивать под свою задачу (например правильно расположить данные для SSE-инструкций). Мне важна скорость, а не универсальность.
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
27.04.2011, 01:01 8
darkAngel, Не столь сильно уменьшается скорость, все же в boost и stl люди тоже думали о производительности)
0
274 / 175 / 12
Регистрация: 14.03.2010
Сообщений: 501
27.04.2011, 02:22 9
darkAngel, опиши задачу подробнее. Возможно, можно сделать по-другому.

Кстати, на будущее: важно не абсолютное время работы (одна миллисекунда против двух), а асимптотическое. То есть пропорция, с которой растёт время выполнения программы с увеличением числа входных данных. Так вот в СБШ (стандартной библиотеке шаблонов, она же STL) с этим всё в порядке. Иначе говоря, нужно составлять быстрый алгоритм, а не лезть в дебри излишней оптимизации.
0
Технофашист
228 / 216 / 11
Регистрация: 11.03.2009
Сообщений: 887
27.04.2011, 09:53  [ТС] 10
Я оперирую с большими объёмами данных и вычислений. Для мне каждая лишняя миллисекунда в итоговой картине заметна.

опиши задачу подробнее. Возможно, можно сделать по-другому
Ну нужно было что-то вроде стека - добавляются в конец элементы, но удалять и просматривать можно любой элемент (по индексу).
В стеке хранятся элементы разного типа.
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
27.04.2011, 11:00 11
Цитата Сообщение от darkAngel Посмотреть сообщение
Ну нужно было что-то вроде стека -добавляются в конец элементы, но удалять и просматривать можно любой элемент (по индексу)
Это называется вектор (std::vector), но вы ему тоже не доверяете...

Цитата Сообщение от darkAngel Посмотреть сообщение
Для мне каждая лишняя миллисекунда в итоговой картине заметна.
union'ы могут ооооочень сильно снизить производительность, т.к. компилятор не может выполнить ряд оптимизаций из-за неизвестности типа, с которым происходит работа.

Цитата Сообщение от darkAngel Посмотреть сообщение
В стеке хранятся элементы разного типа
По нормальному реализуй полиморфизм и усё.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
27.04.2011, 13:14 12
Цитата Сообщение от darkAngel Посмотреть сообщение
Ну нужно было что-то вроде стека - добавляются в конец элементы, но удалять и просматривать можно любой элемент (по индексу)
Это массив из union'ов. Массив можно органищовывать хоть ручками, хоть через std::vector - принципиальной разницы нет. В том числе и с точки зрения скорости. Разница будет только при неправильном подходе к задаче

Цитата Сообщение от darkAngel Посмотреть сообщение
Для мне каждая лишняя миллисекунда в итоговой картине заметна
Когда речь идёт о миллисекундах, то "производительность" и "шаблон" - понятия несовместимые, потому как компилятор не имеет права inline'ить шаблонную функцию или метод. Кроме случаев специализации, но если всё специализировать - тогда нафига вообще связываться с шаблоном.

Цитата Сообщение от Deviaphan Посмотреть сообщение
union'ы могут ооооочень сильно снизить производительность, т.к. компилятор не может выполнить ряд оптимизаций из-за неизвестности типа, с которым происходит работа.
Бред. Попробуй привести хотя бы один пример, где из-за union'а производительность снижается. И хотя бы одну оптимизацию, которая не сможет построиться
1
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
27.04.2011, 13:28 13
Цитата Сообщение от Evg Посмотреть сообщение
потому как компилятор не имеет права inline'ить шаблонную функцию или метод.
C какого перепугу?

Цитата Сообщение от Evg Посмотреть сообщение
хотя бы один пример
Если бы я знал, как работает компилятор, я был бы одним из его разработчиков. Модификатор __restrict говорит нам о том, что union мешает оптимизации. Какой именно - вопрос к разработчикам компилятора.

Добавлено через 5 минут
Между прочим, миллисекунда это ОЧЕНЬ много. За одну тысячную секунды столько успевается сделать, что пипец просто...
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
27.04.2011, 13:34 14
Цитата Сообщение от Deviaphan Посмотреть сообщение
C какого перепугу?
С такого, что у шаблонной функции может быть специализация. Если компилятор её видит - проинлайнит, но если не видит, то она может быть где-то вдругом месте описана, а потому инлайнить нельзя. И это - 99% случаев

Цитата Сообщение от Deviaphan Посмотреть сообщение
Модификатор __restrict говорит нам о том, что union мешает оптимизации. Какой именно - вопрос к разработчикам компилятора.
Модификатор restrict говорит о том, то обращения по указателю с модификатором restrict не пересекаются с обращениями по другим указателям. Т.е. если мы имеем код:

C
1
2
3
int *p1, *p2;
*p1 = ...
... = *p2;
То компилятор, ничего не зная о p1 и p2 должен полагать (если не сумеет доказать обратное), что чтение из p2 теоретически может быть по тому же адресу, что и запись в p1, а потому эти два обращения зависимы. Но если ты на один из указателей навесишь модификатор restrict, то это подсказка компилятору, что обращения по этому указателю НЕ пересекаются по адресам с обращениями по другим указателям. При таком раскладе чтение из p2 можно переставить выше записи в p1. Процесс чтения из памяти - это более долгая операция, чем запись, особенно если данных ещё в кэше нет, а потому чтения из памяти компилятор всегда старается закинуть как можно выше (раньше по исполнению). Современные процессоры умеютодновременно исполнять несколько инструкций, а потому пока тормозное чтение долго работает, в параллель что-то другое исполняется. restrict является дополнительной подсказкой для оптимизаций. union тут вообще не при чём
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
27.04.2011, 13:44 15
Цитата Сообщение от Evg Посмотреть сообщение
Модификатор restrict говорит о том
Его есть два раза. Про первый уже сказано. Второй говорит о том, что в пределах заданного пространства используется только один из типов данных в объединении и компилятор может проводить некоторые оптимизации. Да самое примитивное, занести значение в кэш. Если значение может одновременно использоваться с разными типами, то в кэше его уже не подержишь...

Добавлено через 56 секунд
Цитата Сообщение от Evg Посмотреть сообщение
а потому инлайнить нельзя
Заинтересовало. Можно пруф?

Добавлено через 41 секунду
И Link Time Code Generation никто не отменял. А при нём даже из dll инлайнить могёт, не говоря уже о шаблонах.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
27.04.2011, 14:42 16
Цитата Сообщение от Deviaphan Посмотреть сообщение
Второй говорит о том, что в пределах заданного пространства используется только один из типов данных в объединении и компилятор может проводить некоторые оптимизации. Да самое примитивное, занести значение в кэш. Если значение может одновременно использоваться с разными типами, то в кэше его уже не подержишь...
Можешь ссылку на описание кинуть? Потому что на словах ничегоне понял. Сдаётся мне, это есть какое-то расширение, а не стандарт

Цитата Сообщение от Deviaphan Посмотреть сообщение
Заинтересовало. Можно пруф?
Был один из примеров:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Файл t.h
template <class C>
class T
{
  private:
    C x;
  public:
    T();
    C get();
};
 
template <class C>
T<C>::T()
{
  x = 1;
}
 
template <class C>
C T<C>::get()
{
  return x;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
// Файл t1.cc
#include <iostream>
#include "t.h"
 
T<int> t;
 
int
main (void)
{
  std::cout << t.get() << std::endl;
  return 0;
}
C++
1
2
3
4
5
6
7
8
// Файл t2.cc
#include "t.h"
 
template <>
int T<int>::get()
{
  return 2;
}
Компилируем один файл (когда код со специализацией не попадает в линковку):

Код
$ g++ t1.cc && ./a.out
1
Компилируем два файла (при этом в линковку попадает специализация)

Код
$ g++ t1.cc t2.cc && ./a.out
2
Но вот пока писал этот пример, меня начали терзать сомнения, а является ли он корректным с точки зрения стандарта. Т.е. сказано ли в стандарте, что специализация шабона должна быть доступна во всех местах использования шаблона? Если сказано, то я погорячился насчёт инлайна

Цитата Сообщение от Deviaphan Посмотреть сообщение
И Link Time Code Generation никто не отменял
Если я правильно понимаю сей термин, то это не есть что-то особенное. Это всего лишь механизм, при котором множество исходников можно компилить как бы в едином целом, но при этом исходники остаются разнесёнными в разные файлы. К инлайну шаблонов он будет иметь отношение только в том случае, если я не наглючил с примером со специализацией. Да и мало кто пользуется этим из-за сильно увеличивающегося времени компиляции

Добавлено через 7 минут
Я правильно понимаю, что про __restrict в отношении union'а имелся в виду пример из
http://msdn.microsoft.com/en-u... s.80).aspx
Так вот это не есть то самое. Это просто следствие из свойства __restrict: еслинаписан такой union, то программист обязан сам следить за тем, чтобы работа одновременно ввелась только с одним из указателей. К тому, что писал darkAngel это не имеет никакого отношения, потому что речь идёт НЕ о чтении значений из union'а, а о чтении значений из указателя (который записан в union'е)
0
Технофашист
228 / 216 / 11
Регистрация: 11.03.2009
Сообщений: 887
27.04.2011, 15:17  [ТС] 17
union'ы могут ооооочень сильно снизить производительность, т.к. компилятор не может выполнить ряд оптимизаций из-за неизвестности типа, с которым происходит работа.
мне не нужна оптимизация от компилятора, т.к. основные алгоритмы у меня на ассемблере с SSE-инструкциями, а на с++ только структуры данных описаны.

Добавлено через 53 секунды
Это массив из union'ов. Массив можно органищовывать хоть ручками, хоть через std::vector - принципиальной разницы нет. В том числе и с точки зрения скорости. Разница будет только при неправильном подходе к задаче
Да не совсем и массив. Т.к. есть удаление элементов из середины.
В принципе ручками и реализовал список, просто было интересно, можно ли через шаблоны.

Добавлено через 5 минут
а шаблоны вообще решил использовать, т.к. часто ими не пользуюсь, а многие утверждают, что конёк С++ это шаблоны. Вот и решил попробовать.. вроде бы и типы данных разные, а не подошли тут шаблоны.
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
27.04.2011, 15:18 18
Да, я про это MSDN ссылку говорил. Возможно я не всё корректно из неё понял.)

Цитата Сообщение от Evg Посмотреть сообщение
К инлайну шаблонов он будет иметь отношение
LTCG откладывает генерацию кода до этапа компоновки, т.е. когда уже известны все варианты использования, все специализации, все параметры и способы вызовов. Известно всё, что можно узнать. Поэтому компилятор делает туеву хучу оптимизаций. Даже виртуальные вызовы встраивает, если может. А уж шаблоны разрулить для него точно не проблема.
Загляни в STL, например в вектор, там inline куча объявлений.
0
270 / 176 / 46
Регистрация: 12.03.2010
Сообщений: 494
27.04.2011, 15:25 19
Шаблоны компилируются в отдельные классы(функции и т.д.) для каждого набора параметров в месте инстанциирования, соответственно, в этом месте должна быть видна и реализация шаблона (в основном в конце хедера шаблона пишут #include "*.cpp", но некоторые компиляторы предусматривают #pragma implementation). Соответственно с inline и другими оптимизациями нет никаких проблем.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
27.04.2011, 16:04 20
Цитата Сообщение от darkAngel Посмотреть сообщение
а шаблоны вообще решил использовать, т.к. часто ими не пользуюсь, а многие утверждают, что конёк С++ это шаблоны. Вот и решил попробовать.. вроде бы и типы данных разные, а не подошли тут шаблоны.
Шаблоны нужно использовать когда у тебя есть похожие действия над разными типами. Т.е. если бы у тебя был отдельный массив int'ов и отдельный массив float'ов - тут можно шаблоном пользоваться. А вот когда у тебя есть один массив, но элеметом является либо int, либо float, то тут надо union использовать. Поняно, что пацанским принципиальным методом было бы виртуальное наследование, но опять-таки это без шаблонов

Цитата Сообщение от Deviaphan Посмотреть сообщение
Известно всё, что можно узнать
Не совсем всё, потому что библиотеки обычно компилируются без il'а, но не суть. Мне бы сейчас хотелось понять, законно ли специализацию ставить в такое место, где её может быть не видно одним из запусков компилятора. В своём примере я сделал один запуск компилятора и подал в него два файла. Более честным было бы сделать два раздельных запуска компилятора. Суть от этогоне меняется, но проблема более явно описывается.

LTCG - это метод для извращенцев, которые пытаются проблемы проектирования переложить на компилятор. Да и нужен он в первую очередь для таких архитектур, как IA-64 - с предикатными кодами

Цитата Сообщение от Manjak Посмотреть сообщение
для каждого набора параметров в месте инстанциирования, соответственно, в этом месте должна быть видна и реализация шаблона
Речь не о реализации, а о специализации. В мойм примере при компиляции первого исходника специализация не видна. Она находится во втором исходнике. Вот я и засомневался, является ли это корректным
0
27.04.2011, 16:04
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.04.2011, 16:04
Помогаю со студенческими работами здесь

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

Шаблоны
ругается на строку &quot;friend class List&lt;T&gt;;&quot;, вот что пишет: 1&gt;c:\users\slava\documents\visual...

шаблоны в си++
кто может сказать где прблема? List.h #ifndef LIST_H #define LIST_H #include&lt;iostream&gt;...

Шаблоны
Здравствуйте не объясните новичку пару аспектов про шаблоны 1)Зачем они нужны 2)Преимущества...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru