Подтвердить что ты не робот

Наследование и шаблоны в С++ - почему методы невидимы?

Когда шаблон публично наследуется от другого шаблона, не являются ли общедоступные общедоступные методы доступными?

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 дерьмо на этом... Мне нужно упустить что-то совершенно очевидное (мозговой расплав). Помощь?

4b9b3361

Ответ 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

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