С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
5 / 5 / 0
Регистрация: 10.10.2014
Сообщений: 86

Использование вложенного класса

26.01.2017, 15:06. Показов 1201. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток. Решил подтянуть знания в базовых алгоритмах и структурах данных, а заодно попрактиковаться в шаблонах и обобщенном программировании. Сейчас пишу аналог вектора, и возникли трудности с определениями операций сложения и вычитания итераторов с целыми числами. Вот определение классов:
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
template<typename Item>
class MyArrayList
{
    Item * items_;
    int size_;
    int capacity_;
    void GrowArray();
public:
    class iterator
    {
        const MyArrayList<Item> * ptr_;
        int index_;
        iterator(const MyArrayList<Item> * ptr, int index)
            : ptr_(ptr), index_(index) {}
        friend iterator MyArrayList<Item>::begin() const;
        friend iterator MyArrayList<Item>::end() const;
        friend iterator MyArrayList<Item>::rbegin() const;
        friend iterator MyArrayList<Item>::rend() const;
    public:
        iterator()
            : ptr_(nullptr), index_(-1) {}
        void operator++() 
        { ptr_ != nullptr && index_ < ptr_->size_ ? ++index_ : throw std::logic_error("iterator not incrementable"); }
        void operator++(int)
        { operator++(); }
        void operator--() 
        { ptr_ != nullptr && index_ > 0  ? --index_ : throw std::logic_error("iterator not decrementable"); }
        void operator--(int)
        { operator--(); }
        iterator & operator+(const int val);
        iterator & operator-(const int val);
        friend iterator & operator+(const int val, const iterator & iter);
        bool operator==(const iterator & other) const;
        bool operator!=(const iterator & other) const
        { return !operator==(other); }
        Item & operator*() const;
    };
    explicit MyArrayList(const int lenght = 0);
    MyArrayList(const MyArrayList<Item> & other);
    MyArrayList<Item> & operator=(const MyArrayList<Item> & other);
    ~MyArrayList() { delete[] items_; }
    void reserve(const int size);
    Item & at(const int index) const;
    int indexOf(const Item & item) const;
    void insert(const int index, const Item & item);
    void removeAt(const int index);
    void push_back(const Item & item);
    void pop_back();
    void clear();
    void copyTo(Item arr[], int arrIndex) const;
    void swap(MyArrayList<Item> & other);
    bool remove(const Item & item);
    bool contains(const Item & item) const;
    int size() const { return size_; }
    int capacity() const { return capacity_; }
    bool empty() const { return size_ == 0; }
    Item & operator[](const int index) const;
    iterator begin() const { return iterator::iterator(this, 0);  }
    iterator rbegin() const { return iterator(this, size_ - 1); }
    iterator end() const { return iterator(this, size_); }
    iterator rend() const { return iterator(this, -1); }
};
При попытке определить метод сложения таким образом:
C++
1
2
3
4
5
template<typename Item>
iterator & MyArrayList<Item>::iterator::operator+(const int val)
{
    // TODO: insert return statement here
}
компилятор выдает ряд ошибок , из которых ключевой мне кажется "unrecognizable template declaration/definition". Если правильно понимаю, до уточнения метода operator+ компилятор не понимает что такое iterator, т.к. класс имеет область видимости класса MyArrayList.
Я попробовал использовать предопределение класса iterator до определения метода:
C++
1
class iterator;
...но теперь выдает "MyArrayList<Item>::iterator::operat or +': unable to match function definition to an existing declaration"
Пробовал что-то такое:
C++
1
2
3
4
5
auto MyArrayList<Item>::iterator::operator-(const int val)->decltype(*this)
{
    
    return *this;
}
...но в том месте this использовать нельзя, да и вообще странная идея была.
Подскажите, как это сделать правильно?

Добавлено через 4 часа 42 минуты
Так, кстати, тоже нельзя:
C++
1
2
3
4
5
template<typename Item>
MyArrayList<Item>::iterator & MyArrayList<Item>::iterator::operator+(const int val)
{
    // TODO: insert return statement here
}
Неужели никто не подскажет? Это же должно быть очень просто
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.01.2017, 15:06
Ответы с готовыми решениями:

Как вынести описание методов вложенного класса за пределы класса?
Подскажите, пожалуйста, как мне вынести описание методов вложенного класса за пределы класса?

В конструкторе вложенного класса инициализируется приватное поле. Потом вызывается функция-метод этого класса и выводит значение этого поля НО НЕ ТО!
Друзья! Почему так? #include &lt;windows.h&gt; #include &lt;iostream&gt; using namespace std; //Вот главный класс class A{ ...

Вызов метода вложенного класса
class player { public: void showHp() { cout &lt;&lt;&quot;Health: &quot;&lt;&lt; hp&lt;&lt;endl; } void showInvetory() ...

17
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
26.01.2017, 15:12
Цитата Сообщение от 4elovek37 Посмотреть сообщение
Так, кстати, тоже нельзя:
Нужно так:
C++
1
2
3
4
5
template<typename Item>
typename MyArrayList<Item>::iterator & MyArrayList<Item>::iterator::operator+(const int val)
{
    // TODO: insert return statement here
}
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
26.01.2017, 15:14
Цитата Сообщение от DrOffset Посмотреть сообщение
Нужно так:
эм...

вообще то вот так:
C++
1
2
3
4
5
template<typename Item>
auto MyArrayList<Item>::iterator::operator+(const int val)   //<--- убрал ссылку
{
    // TODO: insert return statement here
}
это же не +=
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
26.01.2017, 15:16
Цитата Сообщение от hoggy Посмотреть сообщение
эм...
Я про typename.
А ссылку там и правда не надо возвращать.
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
26.01.2017, 15:38
Цитата Сообщение от 4elovek37 Посмотреть сообщение
компилятор выдает ряд ошибок , из которых ключевой мне кажется "unrecognizable template declaration/definition".
Компилятор не может вывести тип шаблона. Нужно подсказать ему с помощью typename, либо позволить выводить тип с помощью ключевого слова auto (C++14, можно извернуться с decltype для С++11, но думаю не стоит).
0
5 / 5 / 0
Регистрация: 10.10.2014
Сообщений: 86
26.01.2017, 16:46  [ТС]
С использованием typename компилируется, спасибо!
Цитата Сообщение от MrGluck Посмотреть сообщение
Компилятор не может вывести тип шаблона. Нужно подсказать ему с помощью typename
Впервые вижу такой прием. У этого есть какое-нибудь название, что бы нагуглить-почитать? А почему не может вывести? Я полагал что дело тут в области видимости.
Цитата Сообщение от DrOffset Посмотреть сообщение
А ссылку там и правда не надо возвращать.
Верно, это я на автомате написал, правильно будет возвращать по значению
C++
1
2
3
4
5
template<typename Item>
typename MyArrayList<Item>::iterator MyArrayList<Item>::iterator::operator+(const int val)
{
    // TODO: insert return statement here
}
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
26.01.2017, 16:57
4elovek37, для полного просветления советую почитать книгу "Шаблоны C++. Справочник разработчика", раздел про "Зависимые имена шаблонов".

Добавлено через 47 секунд
Для старта можно еще вот это почитать: https://msdn.microsoft.com/ru-... zs2ee.aspx
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
26.01.2017, 17:00
Цитата Сообщение от 4elovek37 Посмотреть сообщение
У этого есть какое-нибудь название, что бы нагуглить-почитать?
Template deduction.
С помощью typename мы явно говорим, что используется тип данных, иначе, компилятор воспринимает это как статическую переменную, объявленную в классе. Ничто ведь не мешает нам создать статическую переменную iterator в классе MyArrayList

Добавлено через 23 секунды
https://blogs.msdn.microsoft.c... arameters/
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
26.01.2017, 19:02
Цитата Сообщение от 4elovek37 Посмотреть сообщение
У этого есть какое-нибудь название, что бы нагуглить-почитать?
Алёнушка годно объясняет:
http://alenacpp.blogspot.ru/2006/08/typename.html
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1820
Регистрация: 18.10.2014
Сообщений: 17,205
26.01.2017, 20:03
Цитата Сообщение от MrGluck Посмотреть сообщение
Template deduction.
С помощью typename мы явно говорим, что используется тип данных, иначе, компилятор воспринимает это как статическую переменную, объявленную в классе. Ничто ведь не мешает нам создать статическую переменную iterator в классе MyArrayList
Все правильно, но к какому-то "template deduction" это никакого отношения не имеет. Даже непонятно, что такое "template deduction".

Также "статические переменные" тут ни при чем. Да и почему именно статические?

-----------------------

Цитата Сообщение от 4elovek37 Посмотреть сообщение
Пробовал что-то такое:
C++
1
2
3
4
auto MyArrayList<Item>::iterator::operator-(const int val)->decltype(*this)
{
    return *this;
}
...но в том месте this использовать нельзя, да и вообще странная идея была.
Подскажите, как это сделать правильно?
"Странная"? Наоборот, все правильно. Ваш оригинальный вариант в этом формате правильно записывается как просто

C++
1
2
3
4
5
template<typename Item>
auto MyArrayList<Item>::iterator::operator+(const int val) -> iterator
{
  ...
}
учитывая, как уже было правильно сказано, что ссылка там ни к чему.

decltype(*this) тоже должно было прекрасно работать, с той только разницей, что decltype(*this) - ссылка, а вам там ссылка не нужна. Пришлось бы делать std::remove_reference<decltype(*this)>::type.
1
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
26.01.2017, 20:08
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
непонятно, что такое "template deduction"
Вывод типа шаблона. Без typename шаблон не может вывести тип, ему нужна подсказка.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Да и почему именно статические?
Потому что именно они соответствуют синтаксису
Цитата Сообщение от 4elovek37 Посмотреть сообщение
MyArrayList<Item>::iterator
То есть это похоже на обращение к статической переменной iterator шаблонного класса MyArrayList с типом Item.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using Item = int;
 
template <typename T>
class MyArrayList
{
public:
    static int iterator;
};
 
template <>
int MyArrayList<Item>::iterator = 1;
 
int main()
{
    std::cout << MyArrayList<Item>::iterator;
}
Глупо, но с точки зрения парсера именно так.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1820
Регистрация: 18.10.2014
Сообщений: 17,205
26.01.2017, 20:13
Цитата Сообщение от MrGluck Посмотреть сообщение
Вывод типа шаблона. Без typename шаблон не может вывести тип, ему нужна подсказка.
Термин "deduction" в С++ в этом контексте никогда не употреблялся. До появления auto термин deduction использовался только в template argument deduction для шаблонов функций. К этой ситуации никакого отношения не имеет даже отдаленно.

Цитата Сообщение от MrGluck Посмотреть сообщение
Потому что именно они соответствуют синтаксису
Синтаксису? А, скажем, нестатические переменные чем не соответствуют данному синтаксису? А члены внутреннего enum чем не соответствуют данному синтаксису?
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
26.01.2017, 20:34
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
в этом контексте никогда не употреблялся
Как тогда правильно звучит "вывод типа шаблона"?
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
А, скажем, нестатические переменные чем не соответствуют синтаксису?
К ним нельзя обратиться с тем же синтаксисом, что я указал выше. А именно
Цитата Сообщение от MrGluck Посмотреть сообщение
MyArrayList<Item>::iterator
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1820
Регистрация: 18.10.2014
Сообщений: 17,205
26.01.2017, 20:41
Цитата Сообщение от MrGluck Посмотреть сообщение
Как тогда правильно звучит "вывод типа шаблона"?
Приведите пример. Что такое "вывод типа шаблона"?

Цитата Сообщение от MrGluck Посмотреть сообщение
К ним нельзя обратиться с тем же синтаксисом, что я указал выше. А именно
Это как это нельзя? Пожалуйста

C++
1
2
3
4
5
6
7
8
9
struct A { 
  int i; 
 
  void foo() {
    A::i = 5; // <- вот он!
  }
 
  int A::*p = &A::i; // <- вот он снова!
};
Синтаксис ClassName::MemberName - это квалифицированное имя члена класса - один из фундаментальнейших синтаксисов С++. Он применим к абсолютно любым членам класса, без исключения.

Другое дело, что возможность обращаться к членам разного вида (через любой синтаксис) зависит от окружающего контекста, но это уже к данному синтаксису отношения не имеет.
2
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
26.01.2017, 21:10
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Приведите пример. Что такое "вывод типа шаблона"?
Всё же для C++17 помимо template argument deduction появился термин class template deduction (http://en.cppreference.com/w/c... _deduction). Или он же Template argument deduction for class templates (http://www.open-std.org/jtc1/s... 091r3.html)
Но я признаю, что обе эти возможности не имеют отношения к данной ситуации. Что-то увидел шаблоны и меня приглючило. Спасибо, что поправили.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Это как это нельзя? Пожалуйста
Согласен, тут важен контекст. А так, чтобы можно было обратиться вне класса и его методов?
0
5 / 5 / 0
Регистрация: 10.10.2014
Сообщений: 86
27.01.2017, 10:14  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
"Странная"? Наоборот, все правильно. Ваш оригинальный вариант в этом формате правильно записывается как просто
C++
1
2
template<typename Item>
auto MyArrayList<Item>::iterator::operator+(const int val) -> iterator
Да, так тоже работает. Все-таки я был близок. Хотя как-то подсознательно стараюсь избегать использования auto где-либо.
Что бы не плодить топики (да и по теме подходит), спрошу здесь же:
А как правильно поступить с friend op+ функцией? По идее, делать её шаблонной нет необходимости - независимо от конкретной специализации она всегда будет вызывать op+ класса итератора, расставляя операнды в "правильном" порядке. Но мне кажется, что сделать её нешаблонной не получится, или я ошибаюсь?
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
27.01.2017, 10:34
del
0
5 / 5 / 0
Регистрация: 10.10.2014
Сообщений: 86
27.01.2017, 13:56  [ТС]
С дружественной функцией пока пришел только к этому:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template<typename Item>
class MyArrayList
{
    //...
        public:
    class iterator
    {
        //...
    public:
        //...
        iterator operator+(const int val) const;
        iterator operator-(const int val) const;
        friend iterator operator+(const int val, const iterator & iter)
        { return iter + val; }
        //...
    };
    //...
};
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.01.2017, 13:56
Помогаю со студенческими работами здесь

Не видит поля вложенного класса
Создаю свою реализацию stl::list. Также есть электронное пособие с учебного заведения, где уже реализован list, не до конца,а в качестве...

Вектор типа вложенного класса
Здравствуйте. Я делаю свой список. Для этого я создала вложенные классы (List -- мой список, его элементы -- объекты класса типа Elem....

Объявление объекта вложенного класса
Есть структура наподобие: template&lt;class T&gt; class A{ //...... public: class B { int dd; int mm; int yy; ...

Описать конструктор вложенного класса
Привет всем! пожалуйста объясните как правильно описать конструктор вложенного класса в .cpp и доступ к переменной (чтобы присвоить...

Реализация методов вложенного класса
Здравствуйте, необходимо реализовать внешний и вложенный закрытый класс, прим.: A.h class A:{ class B:{ int C, D; ...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru