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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.92
Surgery
3 / 3 / 0
Регистрация: 28.09.2013
Сообщений: 32
#1

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

23.01.2014, 22:55. Просмотров 2150. Ответов 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
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Шаблоны и вложенные классы - синтаксис (C++):

Вложенные классы. Что за синтаксис такой? - C++
Всем привет! Писал код с вложенным классом, столкнулся с таким синтаксисом: template &lt;typename Type&gt; class ExternalClass { ...

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

вложенные классы - C++
Здорова господа! Снова мучаю класс String еще не замучал. Не могу скомпилировать программу с вложенным классом вот код: #include...

Вложенные классы - C++
Где можно почитать нормальную информацию о них? Читаю книгу С.Праты там непонятно что(привел внизу скрин таблицы, которую я вообще не...

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

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

27
Убежденный
Ушел с форума
Эксперт С++
15701 / 7211 / 1139
Регистрация: 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 / 0
Регистрация: 28.09.2013
Сообщений: 32
24.01.2014, 00:28  [ТС] #3
Убежденный, Это то понятно, я просто хотел реализацию Node вынести отдельно, как тогда будет?
0
MrGluck
Модератор
Эксперт CЭксперт С++
7491 / 4606 / 692
Регистрация: 29.11.2010
Сообщений: 12,596
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
Убежденный
Ушел с форума
Эксперт С++
15701 / 7211 / 1139
Регистрация: 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
Убежденный
Ушел с форума
Эксперт С++
15701 / 7211 / 1139
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
25.01.2014, 15:51 #7
А где здесь методы iterator ?
0
gray_fox
What a waste!
1522 / 1227 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 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!
1522 / 1227 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 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!
1522 / 1227 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 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!
1522 / 1227 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 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
26.01.2014, 01:26
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.01.2014, 01:26
Привет! Вот еще темы с ответами:

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

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

Композиция двух классов и вложенные классы - C++
Привет, народ! Собственно говоря вот задача. Существуют 2 класса: 1. Создать класс LongLong для работы с целыми числами из 64 бит....

C++ классы полиморфизм шаблоны - C++
Помогите решить ... вот сделал 1 лаб. роботу, немного кривая но сойдет и нужно еще 3-и задания во 2 лабе ... мне кажется то что я попрошу...


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

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

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