Законно ли создание специализации шаблона функции?

StackOverflow https://stackoverflow.com/questions/757270

Вопрос

В C++ специализация шаблона функции должна действовать точно так же, как обычная функция.Означает ли это, что я могу сделать один виртуальный?

Например:

struct A
{
    template <class T> void f();
    template <> virtual void f<int>() {}
};

struct B : A
{
    template <class T> void f();
    template <> virtual void f<int>() {}
};

int main(int argc, char* argv[])
{
    B b;
    A& a = b;
    a.f<int>();
}

Визуальная Студия 2005 дает мне следующую ошибку:

фатальная ошибка C1001:В компиляторе произошла внутренняя ошибка.

Это было полезно?

Решение

Хорошая ошибка компилятора.Для этого типа проверок я всегда прибегаю к Комо компилятор, прежде чем вернуться к стандарту и проверить.

Comeau C/C ++ 4.3.10.1 (6 октября 2008 г. 11:28:09) для Online_Evaluation_beta2 Copyright 1988-2008 Comeau Computing.Все права защищены.Режим: строгие ошибки c ++ c ++ 0x_extensions

«ComeauTest.c», строка 3:ошибка:«Виртуальный» не допускается в шаблоне шаблона функции шаблона виртуальной void f ();^

«ComeauTest.c», строка 10:ошибка:«Виртуальный» не допускается в шаблоне шаблона функции шаблона виртуальной void f ();^

Теперь, как было опубликовано другим пользователем, факт заключается в том, что стандарт не позволяет вам определять виртуальные шаблонные методы.Причина в том, что для всех виртуальных методов в таблице vtable должна быть зарезервирована запись.Проблема в том, что методы шаблона будут определены только тогда, когда они будут созданы (использованы).Это означает, что виртуальная таблица будет иметь разное количество элементов в каждой единице компиляции, в зависимости от количества различных вызовов. е() с разными типами случаются.Тогда ад восстанет...

Если вам нужна шаблонная функция для одного из ее аргументов и одна конкретная версия является виртуальной (обратите внимание на часть аргумента), вы можете это сделать:

class Base
{
public:
   template <typename T> void f( T a ) {}
   virtual void f( int a ) { std::cout << "base" << std::endl; }
};
class Derived : public Base
{
public:
   virtual void f( int a ) { std::cout << "derived" << std::endl; }
};
int main()
{
   Derived d;
   Base& b = d;
   b.f( 5 ); // The compiler will prefer the non-templated method and print "derived"
}

Если вы хотите, чтобы это было обобщено для любого типа, то вам не повезло.Рассмотрите другой тип делегирования вместо полиморфизма (решением может быть агрегирование + делегирование).Дополнительная информация о рассматриваемой проблеме поможет найти решение.

Другие советы

В соответствии с http://www.kuzbass.ru:8086/docs/isocpp/template.html ИСО/МЭК 14882:1998:

-3- Шаблон функции-члена не должен быть виртуальным.

Пример:

template <class T> struct AA {
    template <class C> virtual void g(C);   //  Error
    virtual void f();                       //  OK
};

Как отмечали другие, это неправильный код, поскольку шаблон функции-члена не может быть объявлен. virtual.

Но даже Visual Studio 2012 задыхается от этого:C++ internal compiler error on Visual Studio 2012 Нажмите здесь, чтобы увидеть полный размер

Журналы событий указывают на сбой компилятора. 0xC0000005, или STATUS_ACCESS_VIOLATION.Забавно, как определенная (недопустимая) конструкция кода может привести к сбою компилятора...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top