Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.74
darkAngel
Технофашист
215 / 198 / 4
Регистрация: 11.03.2009
Сообщений: 865
#1

Шаблоны - C++

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

Пусть есть шаблон-структура.
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)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.04.2011, 23:50
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Шаблоны (C++):

«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами». - C++
«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами». Есть ли разница в этих понятиях? Если есть, то в чём? И где (в каких...

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

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

Шаблоны C++ - C++
Написал template на С++, но он нифига не компилица, пишет мол типа не могу string в int преобразовать в строчке int out_param = (int)param;...

Шаблоны - C++
Я разбираюсь с ООП в С++ и застрял на шаблонах, будьте добры приведите пример кода, к примеру там.... вес машины и шаблон,(ну вообщем на...

Шаблоны - C++
// ConsoleApplication176.cpp : Defines the entry point for the console application. // template&lt;class type&gt; struct link { type...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Evg
Эксперт CАвтор FAQ
17810 / 6016 / 388
Регистрация: 30.03.2009
Сообщений: 16,531
Записей в блоге: 26
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-us/libr...(v=vs.80).aspx
Так вот это не есть то самое. Это просто следствие из свойства __restrict: еслинаписан такой union, то программист обязан сам следить за тем, чтобы работа одновременно ввелась только с одним из указателей. К тому, что писал darkAngel это не имеет никакого отношения, потому что речь идёт НЕ о чтении значений из union'а, а о чтении значений из указателя (который записан в union'е)
0
darkAngel
Технофашист
215 / 198 / 4
Регистрация: 11.03.2009
Сообщений: 865
27.04.2011, 15:17  [ТС] #17
union'ы могут ооооочень сильно снизить производительность, т.к. компилятор не может выполнить ряд оптимизаций из-за неизвестности типа, с которым происходит работа.
мне не нужна оптимизация от компилятора, т.к. основные алгоритмы у меня на ассемблере с SSE-инструкциями, а на с++ только структуры данных описаны.

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

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

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

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

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

Цитата Сообщение от Manjak Посмотреть сообщение
для каждого набора параметров в месте инстанциирования, соответственно, в этом месте должна быть видна и реализация шаблона
Речь не о реализации, а о специализации. В мойм примере при компиляции первого исходника специализация не видна. Она находится во втором исходнике. Вот я и засомневался, является ли это корректным
0
Deviaphan
Делаю внезапно и красиво
Эксперт C++
1287 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
27.04.2011, 16:16 #21
Цитата Сообщение от Evg Посмотреть сообщение
Вот я и засомневался, является ли это корректным
Без полного ребилда, наверное некорректно. Ноя только про MSVC, gcc может по другому работает. Вообще, интересный вопрос. А посл запусков у тебя что получилось?

Цитата Сообщение от Evg Посмотреть сообщение
LTCG - это метод для извращенцев, которые пытаются проблемы проектирования переложить на компилятор.
LTCG это не только PGO.)
Кстати, размер тоже на несколько процентов уменьшается. В больших проектах это мегабайты целые.)
Для меня в LTCG только один минус есть: слишком большой размер lib файлов. По сети неинтересно их передавать.)
0
Evg
Эксперт CАвтор FAQ
17810 / 6016 / 388
Регистрация: 30.03.2009
Сообщений: 16,531
Записей в блоге: 26
27.04.2011, 16:28 #22
Цитата Сообщение от Deviaphan Посмотреть сообщение
Без полного ребилда, наверное некорректно.
Всё то, что написано в стандарте, должно одинаково работать независимо от того, как ты его компиляешь.

Цитата Сообщение от Deviaphan Посмотреть сообщение
Ноя только про MSVC, gcc может по другому работает
Они должны работать в соответсвии с тем, что в стандарте сказано. У меня стандарта Си++ нету, вот думаю, может кто в вопросе разбирается - посмотрит

Цитата Сообщение от Deviaphan Посмотреть сообщение
А посл запусков у тебя что получилось?
Я же там привёл результаты запусков: в первом случае 1, во втором - 2
0
Deviaphan
Делаю внезапно и красиво
Эксперт C++
1287 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
27.04.2011, 16:57 #23
Цитата Сообщение от Evg Посмотреть сообщение
Я же там привёл результаты запусков
Сорри, я не догадался, что это они.)))

Про ребилд я почему заговорил. Перекомпилируются только изменившиеся файлы. Если в одном модуле используется шаблон из хэдэра, а в другой добавили специализацию, то первый модуль может не пересобираться. Т.к. в нём ничего не менялось. И, получается, что в одном модуле оказывается "общая" версия, а во втором специализированная.
В общем, я сомневаться сейчас начал.) Надо пример посложнее написать, чтобы не дин вызов был, а в разных модулях. В стандарте копаться не возбуждает что-то. Лучше тестовый пример написать.)
0
Evg
Эксперт CАвтор FAQ
17810 / 6016 / 388
Регистрация: 30.03.2009
Сообщений: 16,531
Записей в блоге: 26
27.04.2011, 17:25 #24
Цитата Сообщение от Deviaphan Посмотреть сообщение
Если в одном модуле используется шаблон из хэдэра, а в другой добавили специализацию, то первый модуль может не пересобираться
А это пофигу. Шаблонная функция реализуется как WEAK, а специализация - как GLOBAL. Если ты пересоберёшь t1.cc, то всё равно на линковке подцепится специализация из t2.cc. По крайней мере постфакум это так, но я незнаю, что там де-юре
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.04.2011, 17:25
Привет! Вот еще темы с ответами:

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

Шаблоны - C++
Когда разделяю реализацию и прототип шаблонной в функции по разным файлам (*.h и *.cpp) происходит ошибка линковки... Я так понимаю, делать...

Шаблоны С++ - C++
template &lt;typename T_sizeCapacity&gt; class SomeClass { public: T_sizeCacity size; }; Как сделать чтобы T_sizeCapacity мог быть...

Шаблоны - C++
Не пойму что я неправильно делаю. Как не переделывал, всё равно не получалось. Может кто сможет чем помочь. А задача следующая-надо было...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
27.04.2011, 17:25
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru