Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.50/14: Рейтинг темы: голосов - 14, средняя оценка - 4.50
Surgery
3 / 3 / 2
Регистрация: 28.09.2013
Сообщений: 32
1

Шаблоны и вложенные классы - синтаксис

23.01.2014, 22:55. Просмотров 2585. Ответов 27
Метки нет (Все метки)

Пишу класс бинарного красно черного дерева, решил сделать структуру узла в нем вложенной, но столкнулся с проблемой непонимания синтаксиса и борьбы с языком
идея примерно такова
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <class T> Tree
{
    template <class ValType> class Node;
    Node<T> root;
    //...
};
//Реализация Node
template <class T> template <class Valtype> class Tree<T>::Node<Valtype> //? уже вопрос, но студия характеризует полное имя этого класса так
{
    Node<Valtype> * left; //тут совсем встрял, компилятор выдает ошибки
// (например, "Node не является шаблоном (???)", ничего не проясняющие и кажется,
// мало связанные с истинной проблемой, аналогично и на Tree<T>::Node<Valtype> * left;
 
}
Вопрос: как же все таки правильно объявить то что мне надо?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.01.2014, 22:55
Ответы с готовыми решениями:

Вложенные классы. Что за синтаксис такой?
Всем привет! Писал код с вложенным классом, столкнулся с таким синтаксисом: ...

Вложенные классы!!
НЕ могу разобраться ка это работает!!! приведите пожалуйста простой пример как...

вложенные классы
Здорова господа! Снова мучаю класс String еще не замучал. Не могу...

Вложенные классы
Где можно почитать нормальную информацию о них? Читаю книгу С.Праты там...

Вложенные классы
class A { private: B b_class; int a; public: A(); }; class B

27
Убежденный
Ушел с форума
Эксперт С++
15998 / 7269 / 1180
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
23.01.2014, 23:36 2
C++
1
2
3
4
5
6
7
8
9
template <typename T> struct Tree
{
    template <typename Valtype> struct Node
    {
        Node<Valtype> *left;
    };
 
    Node<T> root;
};
1
Surgery
3 / 3 / 2
Регистрация: 28.09.2013
Сообщений: 32
24.01.2014, 00:28  [ТС] 3
Убежденный, Это то понятно, я просто хотел реализацию Node вынести отдельно, как тогда будет?
0
MrGluck
Модератор
Эксперт CЭксперт С++
8086 / 4939 / 1431
Регистрация: 29.11.2010
Сообщений: 13,395
24.01.2014, 01:39 4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template <typename T>
struct A
{
    template <typename U>
    struct B
    {
        B();
    };
};
 
template <typename T>
template <typename U>
A<T>::B<U>::B()
{
    std::cout << "Hello world!\n";
}
0
Убежденный
Ушел с форума
Эксперт С++
15998 / 7269 / 1180
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
24.01.2014, 10:37 5
C++
1
2
template <class ValType> class Node;
Node<T> root;
Здесь объявляется тип Node и сразу же размещается экземпляр его класса.
У компилятора даже нет данных о том, сколько байт под него выделить.

C++
1
2
//Реализация Node
template <class T> template <class Valtype> class Tree<T>::Node<Valtype>
И вдруг ниже появляется "реализация" типа. Это против правил С++.
Нельзя сначала написать "struct sometype", а затем где-то ниже "реализовать" ее
через какое-нибудь "struct sometype {};".
0
iDeveloper
0 / 0 / 0
Регистрация: 24.01.2014
Сообщений: 21
25.01.2014, 15:44 6
Привет всем. Есть такой код:
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
template<typename T>
class list
{
protected:
    struct node
    {
        T data;
        node *previous,*next;
        node() : previous{ nullptr }, next{ nullptr } {};
    };
    node* head;
    unsigned short numberOfItems;
public:
    list() : head(nullptr),numberOfItems(0) {}
    ~list();
    void addToBegin(const T& item);
    void addToEnd(const T& item);
    bool addToNpos(const T& item,unsigned short number);
    bool removeItem(unsigned short number);
    bool show() const;
    unsigned short getNumbOfItems() { return numberOfItems; }
    const T& operator[](int);
    class iterator;
    iterator begin();
    iterator end();
};
Как будет выглядеть прототип любого из методов iterator?
0
Убежденный
Ушел с форума
Эксперт С++
15998 / 7269 / 1180
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
25.01.2014, 15:51 7
А где здесь методы iterator ?
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
25.01.2014, 18:04 8
Цитата Сообщение от iDeveloper Посмотреть сообщение
Как будет выглядеть прототип любого из методов iterator?
iterator можно описать примерно так:
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
struct iterator : std::iterator<std::bidirectional_iterator_tag, T> {
 
   using iterator_category = std::bidirectional_iterator_tag;
   using value_type        = T;
   using pointer           = value_type *;
   using reference         = value_type &;
   using difference_type   = std::ptrdiff_t;
 
   iterator() = default;
 
   pointer operator ->() const noexcept;
 
   reference operator *() const;
 
   iterator & operator ++() noexcept;
   iterator operator ++(int) noexcept;
 
   iterator & operator --() noexcept;
   iterator operator --(int) noexcept;
 
   bool operator ==(iterator const& other) const noexcept;
   bool operator !=(iterator const& other) const noexcept;
 
private:
   explicit iterator(node * current) noexcept;
 
   node * current;
};
1
iDeveloper
0 / 0 / 0
Регистрация: 24.01.2014
Сообщений: 21
26.01.2014, 00:08 9
Цитата Сообщение от Убежденный Посмотреть сообщение
А где здесь методы iterator ?
Класс определен отдельно.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<typename T>
class list<T>::iterator
{
    node* pointer;
public:
    iterator() : pointer{ nullptr } {}
    const iterator& operator=(const iterator&);
    iterator& operator++();
    iterator& operator--();
    iterator operator++(int);
    iterator operator--(int);
    iterator operator+(int) const;
    iterator operator-(int) const;
    bool operator!=(const iterator& pr) const { return pointer != pr.pointer; }
    T& operator*();
    const T& operator*() const;
    friend typename list<T>::iterator list<T>::begin() const;
    friend typename list<T>::iterator list<T>::end() const;
};
Добавлено через 2 минуты
Я нашел ответ. Вот код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<typename T>
class list<T>::iterator
{
    node* pointer;
public:
    iterator() : pointer{ nullptr } {}
    const iterator& operator=(const iterator&);
    iterator& operator++();
    iterator& operator--();
    iterator operator++(int);
    iterator operator--(int);
    iterator operator+(int) const;
    iterator operator-(int) const;
    bool operator!=(const iterator& pr) const { return pointer != pr.pointer; }
    T& operator*();
    const T& operator*() const;
    friend typename list<T>::iterator list<T>::begin() const;
    friend typename list<T>::iterator list<T>::end() const;
};
Проблема была вот в чем - надо определить методы iterator, но как выглядят их прототипы?
Например, как будет выглядеть прототип operator++ вне определения класса iterator? Так? :
template<typename T>
list<T>::iterator& list<T>::iterator::operator++() {};
Ответ - почти так. iterator - зависимое имя шаблона list. C++ не знает что такое list<T>::iterator - это может быть и открытым статическим членом list<T>. Нужно явно указать, что list<T>::iterator - тип. Надо использовать слово typename:

template<typename T>
typename list<T>::iterator& list<T>::iterator::operator++() {};
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
26.01.2014, 00:38 10
Цитата Сообщение от iDeveloper Посмотреть сообщение
C++
1
2
iterator operator+(int) const;
iterator operator-(int) const;
Плохая идея добавлять эти операторы - у них будет линейная сложность.
Цитата Сообщение от iDeveloper Посмотреть сообщение
C++
1
2
T& operator*();
const T& operator*() const;
Константность ссылки зависит от константности итератора? Это как то странно, как минимум...

Добавлено через 53 секунды
и нет operator == и operator ->

Добавлено через 10 минут
Цитата Сообщение от gray_fox Посмотреть сообщение
Константность ссылки
ну т.е. константность типа, на который ссылается ссылка )))
0
iDeveloper
0 / 0 / 0
Регистрация: 24.01.2014
Сообщений: 21
26.01.2014, 00:41 11
Цитата Сообщение от gray_fox Посмотреть сообщение
Константность ссылки зависит от константности итератора? Это как то странно, как минимум...
Да, Вы правы. Запутался немного.
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
26.01.2014, 00:42 12
И ещё нет нужных синонимов типов вроде iterator_category, иначе, при использовании алгоритмов например, будет ошибка при инстанциировании std::iterator_traits<>.
0
iDeveloper
0 / 0 / 0
Регистрация: 24.01.2014
Сообщений: 21
26.01.2014, 01:02 13
Цитата Сообщение от gray_fox Посмотреть сообщение
И ещё нет нужных синонимов типов вроде iterator_category, иначе, при использовании алгоритмов например, будет ошибка при инстанциировании std::iterator_traits<>.
Расскажи об этом поподробнее, пожалуйста.
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
26.01.2014, 01:16 14
Цитата Сообщение от iDeveloper Посмотреть сообщение
Расскажи об этом поподробнее, пожалуйста.
iterator_traits позволяет определить свойства итератора - категория, тип ссылаемого элемнта, тип указателя на элемент и пр. Используется например в алгоритмах stl. Тут на англ. http://en.cppreference.com/w/cpp/iterator/iterator_traits
Что бы это работало, нужно либо специализировать iterator_traits для своего типа (как сделано с обычными указателями), либо предоставить в своём типе итератора вложенные псевдонимы типов (как обычно делают).

Добавлено через 3 минуты
Можешь, например, попробовать вызвать std::copy со своими итераторами и узнать, что компилятор об этом думает)
2
iDeveloper
0 / 0 / 0
Регистрация: 24.01.2014
Сообщений: 21
26.01.2014, 01:26 15
Цитата Сообщение от gray_fox Посмотреть сообщение
Можешь, например, попробовать вызвать std::copy со своими итераторами и узнать, что компилятор об этом думает)
Я пробовал for_each

Добавлено через 3 минуты
gray_fox, что такое difference_type ?
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
26.01.2014, 01:37 16
Цитата Сообщение от iDeveloper Посмотреть сообщение
gray_fox, что такое difference_type ?
Целочисленный знаковый тип для представления разницы между итераторами. Сделан по анологии с ptrdiff_t, который является типом результата разницы двух указателей, т.е. это обобщение ptrdiff_t по сути. Собственно, обычно difference_type и есть ptrdiff_t.

Добавлено через 6 минут
Например, если вызвать std::distance, то результат будет иметь тип difference_type, который "связан" с типом переданных итераторов.
0
iDeveloper
0 / 0 / 0
Регистрация: 24.01.2014
Сообщений: 21
26.01.2014, 01:45 17
Для того, чтобы функции STL могли работать с моим классом, мне осталось только(исключая нужные перегруженные операции для конкретных функций) определить эти синонимы? Как их определить? difference_type - расстояние между обектами iterator в памяти?
0
gray_fox
What a waste!
1553 / 1258 / 166
Регистрация: 21.04.2012
Сообщений: 2,636
Завершенные тесты: 3
26.01.2014, 01:54 18
iDeveloper, проще всего унаследоваться от std::iterator, указав категорию итератора и тип элемента, остальное он выведет сам и определит все нужные типы.
C++
1
2
3
struct iterator : std::iterator<std::bidirectional_iterator_tag, T> {
   // ...
};
0
iDeveloper
0 / 0 / 0
Регистрация: 24.01.2014
Сообщений: 21
26.01.2014, 17:27 19
Привет, gray_fox. Где можно найти подробное описание iterator_traits и свойств, меня интересуют reference, pointer, difference_type?. Желательно на русском и с примерами определения классов с собственными итераторами.
0
MrGluck
Модератор
Эксперт CЭксперт С++
8086 / 4939 / 1431
Регистрация: 29.11.2010
Сообщений: 13,395
26.01.2014, 20:47 20
Часть можно почитать тут (англ. man):
http://www.cplusplus.com/reference/iterator/
http://www.cplusplus.com/reference/iterator/iterator_traits/
http://en.cppreference.com/w/cpp/iterator/iterator_tags

Про итераторы (на русском) написано у
Л.Аммерааль - "STL для программистов на C++" но совсем немного
У Страуструпа тоже есть глава посвященная им
Дэвид Р. Мюссер - "С++ и STL - справочное руководство" - тут вроде побольше было

Есть еще на английском Nicolai Josuttis - "The C++ Standart Library: A Tutorial and Reference (20nd edition)". Её советую больше всего из списка
1
26.01.2014, 20:47
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.01.2014, 20:47

Вложенные в друг друга классы
Есть исходный код: class1.h #pragma once #include &quot;class2.h&quot; class class1...

Перегрузка операция + вложенные классы
Уже второй раз прошу помощи, никто толком не может помочь( Как правильно...

классы, шаблоны
Всем добра, Буду очень признателен получить помощь в очередной раз. ...


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

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

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