Метод шаблона обращается к объявленному классу вперед, не может быть скомпилирован только без этого указателя - PullRequest
4 голосов
/ 13 февраля 2020

Когда я компилирую следующий код с последней версией Visual Studio, он успешно компилируется.

class C;

class T
{
public:
    template<typename A>
    void f();

private:
    C* c;
};

int main()
{
    T t;
    t.f<int>();
}

template<typename A>
void T::f()
{
    this->c->g();
}

class C
{
public:
    void g() {}
};

Но когда я удаляю this-> из this->c->g(), компиляция завершается с C2027: use of undefined type 'C'.

Когда я делаю метод f не шаблонным, он не компилируется независимо от того, представлены ли this-> или нет, так что я думаю, что это связано с компиляцией / созданием шаблона, но я не могу понять. Я прочитал этот ответ , но не является ли c и g однозначным в T::f()?

Итак, вопрос в следующем: Какова роль this-> здесь?


Отличия компилятора:

+-----------------------+---------------------+----------------------+--------------+
|                       | Template, w/ this-> | Template, w/o this-> | Non-Template |
+-----------------------+---------------------+----------------------+--------------+
| Visual Studio 16.3.10 | Success             | Fail                 | Fail         |
| x64 msvc v19.24       | Success             | Success              | Fail         |
| x86-64 gcc 9.2        | Success w/ warning  | Success w/ warning   | Fail         |
| x86-64 clang 9.0.0    | Fail                | Fail                 | Fail         |
+-----------------------+---------------------+----------------------+--------------+

x64 msvc v19.24, x86-64 gcc 9.2 и x86-64 clang 9.0.0 тестируются с помощью Compiler Explorer.

1 Ответ

1 голос
/ 14 февраля 2020

Программа неправильно сформирована с отчетом о недоставке из-за C ++ 17 [temp.res] /8.3:

Программа некорректна, диагностика не требуется c требуется, если:

  • [...]
  • гипотетическая реализация шаблона сразу после его определения будет некорректной из-за конструкции, которая не зависит от параметра шаблона,

Гипотетическая реализация некорректна, потому что c->g используется, когда c имеет указатель на неполный тип, и на это не влияет параметр шаблона A.

Таким образом, это вопрос качества реализации, независимо от того, возникла ли ошибка.

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