Наследование и шаблоны в С++ - почему методы невидимы?
Когда шаблон публично наследуется от другого шаблона, не являются ли общедоступные общедоступные методы доступными?
template <int a>
class Test {
public:
Test() {}
int MyMethod1() { return a; }
};
template <int b>
class Another : public Test<b>
{
public:
Another() {}
void MyMethod2() {
MyMethod1();
}
};
int main()
{
Another<5> a;
a.MyMethod1();
a.MyMethod2();
}
Ну, GCC дерьмо на этом... Мне нужно упустить что-то совершенно очевидное (мозговой расплав). Помощь?
Ответы
Ответ 1
Это часть правил, касающихся зависимых имен. Method1
не является зависимым именем в области Method2
. Поэтому компилятор не ищет его в зависимых базовых классах.
Есть два способа исправить это: Использование this
или указание базового типа. Подробнее об этом недавнем сообщении или в часто задаваемые вопросы по С++. Также обратите внимание, что вы пропустили общедоступное ключевое слово и полуточку. Здесь фиксированная версия вашего кода.
template <int a>
class Test {
public:
Test() {}
int MyMethod1() { return a; }
};
template <int b>
class Another : public Test<b>
{
public:
Another() {}
void MyMethod2() {
Test<b>::MyMethod1();
}
};
int main()
{
Another<5> a;
a.MyMethod1();
a.MyMethod2();
}
Ответ 2
Вы должны полностью квалифицировать MyMethod1
. Стандарт С++ четко указывает это в 14.6.2/3:
В определении шаблона класса или члена шаблона класса, если базовый класс шаблона класса зависит от параметра шаблона, область базового класса не рассматривается при поиске неквалифицированного имени либо в точке определения шаблона или члена класса или во время создания шаблона или члена класса.
Итак, вы должны написать:
void MyMethod2() {
Test<b>::MyMethod1();
}
Ответ 3
main нужен тип возврата.
Класс Другой нуждается в завершающей полуколонии.
class Еще нужно, чтобы его члены были общедоступными.
Кроме того, методы обычно не считаются невидимыми; методы были недоступны без ключевого слова открытого доступа.
Ответ 4
Я очистил ваш код до этого:
template <int a>
class Test {
public:
Test() {}
int MyMethod1() { return a; }
};
template <int b>
class Another : public Test<b>
{
public:
Another() {}
void MyMethod2() {
MyMethod1();
}
};
int main()
{
Another<5> a;
a.MyMethod1();
a.MyMethod2();
}
И скомпилирован с -fpermissive
без проблем (возможно, вы можете решить эту проблему).
Ответ 5
Я думаю, что вы просто пропустили публикацию: в верхней части другого определения. Для таких вопросов обычно полезно размещать сообщения об ошибках, которые вы получаете.