Влияние виртуального на использование члена класса шаблона

Я (смутно) знаю, что шаблон не создается, если он не используется. Например, следующий код скомпилируется нормально, хотя T::type не имеет смысла, когда T = int,

template<typename T>
struct A
{
    void f() { using type = typename T::type; }
};

A<int> a; //ok

Компилируется потому что f() не используется, поэтому он не создан - таким образом, действительностьT::type остается непроверенным. Неважно, если какая-то другая функция- член g() звонки f(),

template<typename T>
struct A
{
    void f() { using type = typename T::type; }

    void g() { f(); } //Is f() still unused?
};

A<int> a; //ok

Это также составляет штрафы. Но здесь я осознаю неопределенность в моем понимании определения "использование". Я спрашиваю:

  • Является f() все еще не используется? Как именно?

Я ясно вижу, как он используется внутри g(), Но потом я подумал, так как g() не используется, f() также не используется, с точки зрения реализации. Это кажется достаточно разумным. до сих пор.

Однако, если я добавлю virtual ключевое слово для g()не компилируется:

template<typename T>
struct A
{
    void f() { using type = typename T::type; }

    virtual void g() { f(); } //Now f() is used? How exactly?
};

A<int> a; //error

Это приводит к ошибке компиляции, потому что теперь он пытается создать экземпляр f(), Я не понимаю это поведение.

Кто-нибудь может объяснить это? Особенно влияние virtual Ключевое слово по определению "использование" члена шаблона класса.

1 ответ

Решение

Беглый взгляд на 3.2 [basic.def.odr] дает:

3 / [...] Виртуальная функция-член используется odr, если она не является чистой. [...]

И я также нашел в 14.7.1 [temp.inst]:

10 / Реализация не должна неявно создавать экземпляр шаблона функции, шаблона элемента, не виртуальной функции-члена, класса-члена или статического члена данных шаблона класса, который не требует создания экземпляра. Не определено, будет ли реализация неявно создавать экземпляр виртуальной функции-члена шаблона класса, если в противном случае функция виртуального члена не была бы создана. (акцент мой)

Так что... я бы сказал, что virtual метод всегда будет создан.

В прагматических терминах я бы ожидал, что компилятор создаст экземпляр виртуальной таблицы шаблонного класса при создании экземпляра класса; и, таким образом, немедленно создать все экземпляры virtual функции-члены этого класса (поэтому он может ссылаться на функции из виртуальной таблицы).

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