Как объявить Iterator для множества стеков в C ++

0

Я создаю класс, представляющий собой набор стеков. Я хочу использовать итератор, чтобы получить элемент в конце и получить доступ к его функциям. Но я получаю следующую ошибку

setOfStacks.cpp:40:6: error: expected ';' after expression
            set< stack<Type> >::iterator it = mSetOfStacks.end();
               ^
               ;

Класс работает с шаблоном и объявляется следующим образом:

template<typename Type>
class SetOfStacks 
{
public: 
        SetOfStacks(int capacityPerStack);
    void            push(Type object);
    Type            pop();
    bool            isEmpty();
private:
    void            createNewStackWithElem(Type object);
private:

        int                 mStackCapacity;
        set<stack<Type> >   mSetOfStacks;
};

Затем в моей функции вставки я пытаюсь получить стек в конце

set< stack<Type> >::iterator it = mSetOfStacks.end();
if( *it->size() < mStackCapacity )
    *it->push(object);

где я получаю ошибку при попытке объявить итератор setOfStacks.cpp: 40: 6: error: expected ';' после выражения

также, я попробовал

set<stack<Type> >::iterator it = mSetOfStacks.end(); 

но это не сработало

Вся функция push

template<typename Type>
void SetOfStacks<Type>::push(Type object) {
    // if entire set is empty make a new stack
    if( mSetOfStacks.empty() ) {
        stack<Type> newStack;
        newStack.push(object);

        mSetOfStacks.insert(newStack);
    }
    else {
        // check if current stack within limits
        set< stack<Type> >::iterator it = mSetOfStacks.end();
        if( *it->size() < mStackCapacity )
            *it->push(object);
        else {
            // duplicate code, make another function
            stack<Type> newStack;
            newStack.push(object);

            mSetOfStacks.insert(newStack);
        }
    }
}
  • 0
    В вашем коде много ошибок, но эта конкретная ошибка, похоже, не совпадает. Можете ли вы опубликовать немного больше контекстного кода?
  • 0
    Можете ли вы опубликовать всю функцию вставки.
Показать ещё 2 комментария
Теги:
set
iterator
stack
stl

3 ответа

3
Лучший ответ

Внутри шаблона функции вложенный iterator имен является зависимым именем, которое считается объектом, а не типом. Вы хотите указать, что iterator является типом, используя ключевое слово typename:

typename std::set<std::stack<Type> >::iterator it = mSetOfStacks.end();
// ^-- here

Шаблоны анализируются в два этапа: на первом этапе код анализируется для его логических компонентов без каких-либо знаний о аргументах или объектах шаблона в зависимости от аргументов шаблона. Если есть вложенное имя в зависимости от аргумента шаблона, компилятор предполагает, что это имя является объектом, а не типом, если вы явно не укажете, что это тип, используя ключевое слово typename.

  • 0
    Я также столкнулся с другой проблемой. после получения значения моего итератора я пытаюсь получить доступ к функциям стека, но когда я пытаюсь выдвинуть значение, я получаю сообщение об ошибке в code typename set< stack<Type> >::iterator it = mSetOfStacks.end(); --it; if( it->size() < mStackCapacity ) { it->push(object); } else { вставляемого code typename set< stack<Type> >::iterator it = mSetOfStacks.end(); --it; if( it->size() < mStackCapacity ) { it->push(object); } else { функции code typename set< stack<Type> >::iterator it = mSetOfStacks.end(); --it; if( it->size() < mStackCapacity ) { it->push(object); } else { функция-член 'push' недопустима: аргумент 'this' имеет тип 'const std :: stack <int, std :: deque <int, std :: allocator <int>>>', но функция не помечена как const IT-> толчок (объект);
  • 0
    @SakibShaikh: конечно, вы не можете изменить ключ std::set<...> ! Это испортило бы его внутренние инварианты. Кажется, вы хотите что-то вроде std::list<...> .
1

auto - идеальное ключевое слово для этого:

auto it = mSetOfStacks.end();
1

При использовании С++ 11 вам не нужно указывать тип итератора для определения итератора при инициализации его из-за чего-то вроде mSetOfStacks.end(). Вместо этого вы можете использовать auto:

auto it = mSetOfStacks.end();

Кроме того, вы не должны обращаться к этому итератору, так как он указывает один элемент за конец. Если вы хотите, чтобы последний элемент в наборе, уменьшите итератор до его доступа:

--it;
// then use *it

или ссылаться на последний набор с помощью ссылочной переменной:

auto & lastSet = *(--it);
// then use lastSet instead of *it

Если ваш компилятор не поддерживает auto использование, используйте решение Dietmar.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню