Наследование и шаблоны в C++ - почему унаследованные члены невидимы?
Когда шаблон публично наследуется от другого шаблона, разве базовые публичные методы не должны быть доступны?
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 об этом говорит... Я, должно быть, упускаю что-то совершенно очевидное (таяние мозга). Помогите?
5 ответов
Это часть правил, касающихся зависимых имен. Method1
не является зависимым именем в области Method2
, Таким образом, компилятор не ищет его в зависимых базовых классах.
Есть два способа исправить это: Использование this
или указав базовый тип. Более подробно об этом самом последнем посте или на C++ FAQ. Также обратите внимание, что вы пропустили ключевое слово public и точку с запятой. Вот исправленная версия вашего кода.
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();
}
Вы должны полностью пройти отбор MyMethod1
, Стандарт C++ четко утверждает это в 14.6.2/3:
В определении шаблона класса или члена шаблона класса, если базовый класс шаблона класса зависит от параметра-шаблона, область действия базового класса не проверяется при поиске неквалифицированного имени ни в точке определения класса шаблон или член или во время создания шаблона класса или члена.
Итак, вы должны написать:
void MyMethod2() {
Test<b>::MyMethod1();
}
Основное нуждается в типе возврата.
Класс Другой нуждается в завершающей точке с запятой.
Класс Другой нуждается в своих членах, чтобы быть публичным.
Кроме того, методы обычно не считаются невидимыми; методы были недоступны без общедоступного ключевого слова.
Я очистил ваш код к этому:
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
без проблем (возможно, вы сможете решить эту проблему).
Я думаю, что вы просто скучаете по публике: на вершине другого определения. Для подобных вопросов обычно полезно публиковать сообщения об ошибках, которые вы получаете.