Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
 Аватар для gomodril
6 / 6 / 0
Регистрация: 10.10.2012
Сообщений: 140

Для чего необходимо ключевое слово typename

07.04.2016, 20:18. Показов 1262. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Исходные данные.
Есть класс CAppContainer, заголовочный файл appcontainer.h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifndef APPCONTAINER_H
#define APPCONTAINER_H
 
#include "headers.h"
#include "utils.h"
 
template <typename TComparator>
class CAppContainer
{
private:
   typedef std::map<int64_t, Order*>      TOrdersById;
   typedef std::set<Order*, TComparator>  TOrdersByPrice;
 
   TOrdersByPrice _orders_aggregate;                        // содержит агрегированные заявки отсортированые по цене
   TOrdersById    _orders_active;                           // активные заявки, отсортированные по ord_id
   TComparator    _compare;
 
   typename TOrdersByPrice::iterator   findOrderByPrice(const double& price);
   void              modifyAggregateAmount(const double& price, int32_t amount); // вычесть объем заявки из агрегированного объема
 
public:
                     CAppContainer(void);
   void              add(const OrderDataEx* order);                  // добавление активной заявки, создание новой агрегированной завки
   void              remove(int64_t id);                             // удалить активную заявку. вычесть ее объем из агрегированной
   void              modify(int64_t id, int32_t amount);             // изменить объем активной заявки. поправить агрегированную запись
   void              clear();                                        // удалить все заявки (активные и агрегированные)
   void              onClearDeleted(const RevisionInfo* rev_info);   // обработчик CG_MSG_P2REPL_CLEARDELETED
   template <typename InputIterator>
   void              print_elements(InputIterator first,             // вывод на печать элементов типа 'CAppContainer'
                                    InputIterator last, FILE* file, int max_count);
   void              print(FILE* file, int depth, bool reverse);     // записать содержимое агрегированных заявок в текстовый файл
};
 
#endif // APPCONTAINER_H
appcontainer.cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
template <typename TComparator>
typename TOrdersByPrice::iterator CAppContainer<TComparator>::findOrderByPrice(const double& price) {
      return std::find_if(_orders_aggregate.begin(), _orders_aggregate.end(), std::bind2nd(price_equal(), price));
}
template <typename TComparator>
void CAppContainer<TComparator>::modifyAggregateAmount(const double& price, int32_t amount) {
   log_trace("Modifying aggregate amount, price = %10.2lf", price);
   typename TOrdersByPrice::iterator itPriceOrder = findOrderByPrice(price);
   if(itPriceOrder == _orders_aggregate.end()) {
      fprintf(stderr, "\nGot remove operator for non-existing order price=%.2lf\n", price);
      return;
   }
 
   if((*itPriceOrder)->amount == amount) {
      smart_ptr<Order> apOrder(*itPriceOrder); // delete helper
      _orders_aggregate.erase(itPriceOrder);
      log_trace("Deleting aggregate record");
   } else {
      (*itPriceOrder)->amount -= amount;
      assert((*itPriceOrder)->amount > 0);
      log_trace("Aggregate amount %d -> %d", (*itPriceOrder)->amount + amount, (*itPriceOrder)->amount);
   }
}
...
Почему при раздельной компоновке класса происходит ошибка при компиляции error: 'TOrdersByPrice' has not been declared
typename TOrdersByPrice::iterator CAppContainer<TComparator>::findOrderByP rice(const double& price)
Хотя при объявлении и определении класса одним листингом ошибки нет?
1
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.04.2016, 20:18
Ответы с готовыми решениями:

Для чего нужен шаблон <typename T>
Здравствуйте. template &lt;typename T&gt; T CLAMP(const T&amp; value, const T&amp; low, const T&amp; high) { return (value &lt; low) ? low : ((value...

Ключевое слово const для возвращаемого значения из функции
Думал что это означает следующее &quot;Нельзя изменить значение которое вернет функция&quot; Но проверил и оказалось что это не так ...

Определить, в введенном предложении слово, которое состоит из тех же букв, что и заданное ключевое слово.
Ввести предложения и ключевое слово. Определить, в введенном предложении слово, которое состоит из тех же букв, что и заданное ключевое...

4
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13196 / 6831 / 1822
Регистрация: 18.10.2014
Сообщений: 17,291
07.04.2016, 20:35
Цитата Сообщение от gomodril Посмотреть сообщение
Хотя при объявлении и определении класса одним листингом ошибки нет?
Ошибки не будет не "при объявлении и определении класса одним листингом", а именно при определении методов класса внутри определения класса, т.е. именно там где и TOrdersByPrice определено.

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

А количество листингов тут роли не играет.

Например

C++
1
2
3
4
5
6
7
8
9
10
struct S
{
   typedef int Type;
   Type foo(Type i);
};
 
S::Type foo(Type i)
{
  return i;
}
Обратите внимание, что при определении метода за пределами класса тип возвращаемого значения мы вынуждены указывать как S::Type, а тип параметра можно по-прежнему указывать как просто Type.

Вот также и в вашем случае, при определении метода за пределами класса тип возвращаемого занчения придется указывать через typename CAppContainer<TComparator>::TOrdersByPrice, например

C++
1
2
3
4
template <typename TComparator>
typename CAppContainer<TComparator>::TOrdersByPrice::iterator CAppContainer<TComparator>::findOrderByPrice(const double& price) {
      return std::find_if(_orders_aggregate.begin(), _orders_aggregate.end(), std::bind2nd(price_equal(), price));
}
Хотя сама идея переноса определений шаблонных методов в .cpp файл вызывает недоумение. Это же просто линковаться потом не будет.
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
07.04.2016, 20:43
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
придется указывать через typenam
а почему надо typename ? Почему без него никак?
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
07.04.2016, 21:26
rikimaru2013, http://alenacpp.blogspot.ru/2006/08/typename.html
1
 Аватар для gomodril
6 / 6 / 0
Регистрация: 10.10.2012
Сообщений: 140
08.04.2016, 02:39  [ТС]
спасибо за разъяснение
а разве можно не выносить шаблонный метод в срр файл, если остальные методы вынесены?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.04.2016, 02:39
Помогаю со студенческими работами здесь

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

Ключевое слово this
Можно какой-нибудь простой пример, чтобы понять зачем это нужно?

Ключевое слово try
Вот вчера печатал программу и нечаяно поставил вместо слова tru слово try и оно выделелось жырным шрифтом.А в моем компиляторе все ключевые...

Ключевое слово break
Как правильно надо использовать ключевое слово break??

Ключевое слово register
локальная переменная которая задается : register int a; так же будет локальной и сохраняется в регистр если есть свободное место. но...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru