Наследование и шаблоны в 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 без проблем (возможно, вы сможете решить эту проблему).

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

Другие вопросы по тегам