Внутреннее наследование шаблонных классов - PullRequest
2 голосов
/ 11 октября 2019

У меня есть следующий код: https://gist.github.com/PatrikValkovic/50329975f86e0328ff1f85fda17a23f3, живой пример здесь: http://cpp.sh/675a3.

Короче говоря, у меня есть класс A с внутренним классом B и классом D, который должен наследоваться отB . Код работает, когда класс D объявлен внутри класса A (как прокомментировано). Однако когда я перемещаю объявление за пределы класса A (как в примере), компилятор жалуется, что A<T>::B<U> не является типом. Что плохого в синтаксисе?

// Example program
#include <iostream>
#include <string>

using namespace std;

template<typename T>
class A
{
public:
    template<typename U>
    class B;    

    /*
    class D : public B<int>
    {
    public:
        void method2() {
            cout << "Method 2" << endl;
            this->method1();
        }
    };
    */

    class D;
};

template<typename T>
template<typename U>
class A<T>::B 
{
public:
    void method1() {
        T x;
        cout << "Method 1: " << x << endl;
    }
};

template<typename T>
class A<T>::D : public A<T>::B<int>
{
public:
    void method2() {
        cout << "Method 2" << endl;
        this->method1();
    }
};

int main()
{
  A<int>::D b;
  b.method2();
}

1 Ответ

2 голосов
/ 11 октября 2019

Это один из тех действительно странных крайних случаев в языке C ++, который имеет необычное исправление. Проблема здесь:

template<typename T>
class A<T>::D : public A<T>::B<int>
                       ^^^^^^^^^^^^

Проблема в том, что вы пытаетесь использовать шаблонный класс B, который является зависимым именем внутри A (то есть, B является шаблономвложенный в другой тип, который зависит от аргумента шаблона, здесь, T). По умолчанию C ++ не будет относиться к зависимым именам как к именам типов или имен шаблонов, и вы должны явно сказать компилятору «да, это имя шаблона», используя ключевое слово template необычным способом. :

template<typename T>
class A<T>::D : public A<T>::template B<int>
                             ^^^^^^^^

Это говорит C ++ "внутри A<T> вы найдете шаблон типа с именем B. Пожалуйста, используйте этот шаблон с аргументом int."

Это похоже на то, как вы должны использовать ключевое слово typename с зависимыми типами - оно говорит компилятору «да, это имя типа». Здесь ключевое слово template сообщает компилятору «да, это имя шаблона».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...