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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.92
Surgery
3 / 3 / 0
Регистрация: 28.09.2013
Сообщений: 32
23.01.2014, 22:55     Шаблоны и вложенные классы - синтаксис #1
Пишу класс бинарного красно черного дерева, решил сделать структуру узла в нем вложенной, но столкнулся с проблемой непонимания синтаксиса и борьбы с языком
идея примерно такова
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;
 
}
Вопрос: как же все таки правильно объявить то что мне надо?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.01.2014, 22:55     Шаблоны и вложенные классы - синтаксис
Посмотрите здесь:

Перегрузка операция + вложенные классы C++
Композиция двух классов и вложенные классы C++
C++ Вложенные классы!!
C++ классы полиморфизм шаблоны C++
вложенные классы C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Убежденный
Системный программист
 Аватар для Убежденный
14183 / 6198 / 984
Регистрация: 02.05.2013
Сообщений: 10,324
Завершенные тесты: 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;
};
Surgery
3 / 3 / 0
Регистрация: 28.09.2013
Сообщений: 32
24.01.2014, 00:28  [ТС]     Шаблоны и вложенные классы - синтаксис #3
Убежденный, Это то понятно, я просто хотел реализацию Node вынести отдельно, как тогда будет?
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4920 / 2663 / 243
Регистрация: 29.11.2010
Сообщений: 7,405
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";
}
Убежденный
Системный программист
 Аватар для Убежденный
14183 / 6198 / 984
Регистрация: 02.05.2013
Сообщений: 10,324
Завершенные тесты: 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 {};".
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?
Убежденный
Системный программист
 Аватар для Убежденный
14183 / 6198 / 984
Регистрация: 02.05.2013
Сообщений: 10,324
Завершенные тесты: 1
25.01.2014, 15:51     Шаблоны и вложенные классы - синтаксис #7
А где здесь методы iterator ?
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 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;
};
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++() {};
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 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 Посмотреть сообщение
Константность ссылки
ну т.е. константность типа, на который ссылается ссылка )))
iDeveloper
0 / 0 / 0
Регистрация: 24.01.2014
Сообщений: 21
26.01.2014, 00:41     Шаблоны и вложенные классы - синтаксис #11
Цитата Сообщение от gray_fox Посмотреть сообщение
Константность ссылки зависит от константности итератора? Это как то странно, как минимум...
Да, Вы правы. Запутался немного.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
26.01.2014, 00:42     Шаблоны и вложенные классы - синтаксис #12
И ещё нет нужных синонимов типов вроде iterator_category, иначе, при использовании алгоритмов например, будет ошибка при инстанциировании std::iterator_traits<>.
iDeveloper
0 / 0 / 0
Регистрация: 24.01.2014
Сообщений: 21
26.01.2014, 01:02     Шаблоны и вложенные классы - синтаксис #13
Цитата Сообщение от gray_fox Посмотреть сообщение
И ещё нет нужных синонимов типов вроде iterator_category, иначе, при использовании алгоритмов например, будет ошибка при инстанциировании std::iterator_traits<>.
Расскажи об этом поподробнее, пожалуйста.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
26.01.2014, 01:16     Шаблоны и вложенные классы - синтаксис #14
Цитата Сообщение от iDeveloper Посмотреть сообщение
Расскажи об этом поподробнее, пожалуйста.
iterator_traits позволяет определить свойства итератора - категория, тип ссылаемого элемнта, тип указателя на элемент и пр. Используется например в алгоритмах stl. Тут на англ. http://en.cppreference.com/w/cpp/ite...terator_traits
Что бы это работало, нужно либо специализировать iterator_traits для своего типа (как сделано с обычными указателями), либо предоставить в своём типе итератора вложенные псевдонимы типов (как обычно делают).

Добавлено через 3 минуты
Можешь, например, попробовать вызвать std::copy со своими итераторами и узнать, что компилятор об этом думает)
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 ?
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 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, который "связан" с типом переданных итераторов.
iDeveloper
0 / 0 / 0
Регистрация: 24.01.2014
Сообщений: 21
26.01.2014, 01:45     Шаблоны и вложенные классы - синтаксис #17
Для того, чтобы функции STL могли работать с моим классом, мне осталось только(исключая нужные перегруженные операции для конкретных функций) определить эти синонимы? Как их определить? difference_type - расстояние между обектами iterator в памяти?
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
26.01.2014, 01:54     Шаблоны и вложенные классы - синтаксис #18
iDeveloper, проще всего унаследоваться от std::iterator, указав категорию итератора и тип элемента, остальное он выведет сам и определит все нужные типы.
C++
1
2
3
struct iterator : std::iterator<std::bidirectional_iterator_tag, T> {
   // ...
};
iDeveloper
0 / 0 / 0
Регистрация: 24.01.2014
Сообщений: 21
26.01.2014, 17:27     Шаблоны и вложенные классы - синтаксис #19
Привет, gray_fox. Где можно найти подробное описание iterator_traits и свойств, меня интересуют reference, pointer, difference_type?. Желательно на русском и с примерами определения классов с собственными итераторами.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.01.2014, 20:47     Шаблоны и вложенные классы - синтаксис
Еще ссылки по теме:

C++ Вложенные классы
C++ [Классы, Наследование, Шаблоны] Добавление записи в список
Вложенные классы. Что за синтаксис такой? C++

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

Или воспользуйтесь поиском по форуму:
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4920 / 2663 / 243
Регистрация: 29.11.2010
Сообщений: 7,405
26.01.2014, 20:47     Шаблоны и вложенные классы - синтаксис #20
Часть можно почитать тут (англ. man):
http://www.cplusplus.com/reference/iterator/
http://www.cplusplus.com/reference/i...erator_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)". Её советую больше всего из списка
Yandex
Объявления
26.01.2014, 20:47     Шаблоны и вложенные классы - синтаксис
Ответ Создать тему
Опции темы

Текущее время: 03:50. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru