#c #class
Вопрос:
class Solution {
public:
void func(test t)
{
}
class test
{
};
};
Компиляция этого приводит к ошибке
error: unknown type name 'test'
void func(test t)
Я добавил область в тест типа
class Solution {
public:
void func(Solution::test t)
{
}
class test
{
};
};
Но это дает
test.cpp:47:25: error: no type named 'test' in 'Solution'
void func(Solution::test t)
Я предполагаю, что это связано с тем, что функция test
не знает о class test
том, что она объявлена ниже. Поэтому я добавил объявление выше test
class Solution {
public:
class test;
void func(Solution::test t)
{
}
class test
{
};
};
Теперь этот код компилируется (он также компилируется, если я удалю Solution::
область действия), но у меня есть 2 вопроса.
(1) Если func
вызывается какая-либо другая функция-член, которая была определена ниже, она работает, но почему в этом случае она жалуется на незнание класса test
?
(2) Есть ли какой-либо смысл добавлять Solution::
в этой ситуации?
Комментарии:
1. @RetiredNinja «Компиляторы читают сверху вниз» — но почему это не относится к ситуации, когда, например,
func()
вызывается другая функция, определенная ниже?2. Объявления (включая прототипы определений функций в классе) обрабатываются сначала сверху вниз. Тела функций обрабатываются только после того, как известны объявления.
Ответ №1:
То, с чем вы здесь имеете дело, называется контекстом полного класса класса, который
Контекст полного класса класса (шаблона) является
- тело функции ([dcl.fct.def.general]),
- аргумент по умолчанию ([dcl.fct.по умолчанию]),
- аргумент шаблона по умолчанию ([temp.param]),
- описатель исключений ([кроме.spec]), или
- инициализатор элемента по умолчанию
в пределах спецификации члена класса или шаблона класса.
Параметры функции-члена не являются частью этого, поэтому они должны быть типами, которые уже были определены, чего в данном случае нет. Это работает после class test;
первого добавления, потому что теперь объявлен тип, и это все, что требуется для объявления функции.
Итак, решение состоит в том, чтобы test
сначала определить или объявить его, как вы это делали в своем последнем примере.