Компиляция программы, несмотря на использование несуществующих членов

template <typename T>
void list<T>::copyAll(const list &l)
{
if(l.isEmpty()) //if the list-to-copy is empty, we're done
{
first = last = NULL;
}
else
{
node *toFollow = l->yhjfrtydfg;
node *whatever = l.asfqwejfq3fqh23f8hq23r1h23017823r087q1hef;

while(toFollow != NULL)
{
T *newO = new T(*(toFollow->o));
T here = *newO;
insertBack(&here);
toFollow = toFollow->next;
}
}
}

Эта программа компилируется (с остальной частью программы), даже если две строки node *toFollow = l->yhjfrtydfg; а также node *whatever = l.asfqwejfq3fqh23f8hq23r1h23017823r087q1hef; явно сумасшедший вклад. Это странно, потому что обнаружена любая другая ошибка. Любая помощь?

2

Решение

«Зависимые имена» (имена, используемые в шаблонах, значение которых зависит от параметров шаблона) разрешаются только при создании экземпляра шаблона, а не при его определении. Если вы не создадите экземпляр шаблона, он может содержать любые сумасшедшие имена, которые вам нравятся, если он синтаксически правильный.

Ваша программа не сможет скомпилироваться, если ее создать:

list<int> l;
l.copyAll(l); // ERROR
6

Другие решения

Имена, которые зависят от параметра шаблона, разрешаются только после создания экземпляра шаблона. В любом случае разрешаются только независимые имена.

C ++ придумал этот «двухфазный поиск», где фаза 1 — это время первого разбора, а фаза 2 — время создания экземпляра.

Например.:

template <typename T>
void frob() {
foo = 5; // non-dependent, name must exist at this point
T bar;
bar.frobnicate = 7; // dependent, name is looked up upon instantiation

bar->is->a.funny(T::hing); // dependent, likewise looked up later
}
6

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

        T newO = new T(*(toFollow->o));
insertBack(&newO);
toFollow = toFollow->next;

Полностью и полностью сломан. Сначала вы динамически выделяете T, а затем попытаться построить из него T-стека? Нет Т ведет себя так. Затем вы сохраняете указатель на выделенный стеком объект.

2
По вопросам рекламы [email protected]