2011-01-01 2 views
3
class A { 
public: 
    template<typename T> void func(size_t n, T values[]) { ... } 
}; 

class B : public A { 
public: 
    void func(size_t n, uint32_t values[]) { ... } 
}; 

Почему функция B::func()не имеют приоритет над шаблоном функции A::func() при вызове этого кода?Шаблон над методом нешаблонном в производном классе

uint32_t values[5]; 
A* obj = new B(); 
obj->func(5, values); 
+0

Поскольку правила разрешения перегрузки выбирают наиболее одинаковое совпадение по типу и наиболее конкретное (в данном случае не шаблонное). – 9dan

+0

Некоторые указатели от Herb Sutter http://gotw.ca/gotw/049.htm – DumbCoder

+0

Был ли ** не ** предназначен для автора? – peoro

ответ

6

Два reasons-

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

  2. В C++ функции члена шаблона не могут быть помечены как виртуальные. Отчасти это связано с реализацией наиболее часто используемых виртуальных функций - vtables - в сочетании с системой экземпляров шаблонов C++. C++ рассматривает все экземпляры одного и того же шаблона по разным аргументам типа как отдельные функции и генерирует эти экземпляры лениво. Это проблема для реализации vtable, так как vtable требует статического, компиляционного определения количества различных виртуальных функций в классе, а также упорядочения на них. Поскольку виртуальная функция шаблона будет означать неизвестное число и упорядочение виртуальных функций в классе, C++ запрещает это.

+0

re # 2 см. Также [мой ответ] (http://stackoverflow.com/questions/2354210/can-a-member-function-template-be-virtual/2354671#2354671) на запись в FAQ. – sbi

+0

Итак, единственное решение моей проблемы - сделать нетермическую версию func в A (вызов функции шаблона) и переопределить ее в B? – mnn

+0

Это должно сработать. Из любопытства, почему у вас есть функция члена-шаблона, которая производит данные произвольных типов? – templatetypedef

0

A::func() не объявлен как virtual, так что компилятор не будет генерировать виртуальную таблицу и любой другой код, необходимый для вызова B::func() во время выполнения. Он не имеет ничего общего с шаблонами.

+0

-1 для него не имеет ничего общего с шаблонами. –

1

Если вы звоните func на объект/указатель/ссылка типа A, A::func вызывается, поскольку func не является виртуальным (и это не может быть: это шаблон функции).

Вы действительно проверили ваш код?

0

Поскольку B :: func НЕ является перегрузкой функции A :: func и никогда не может быть, независимо от того, что вы делаете. Даже не пытайтесь объявить A :: func виртуальным, потому что не можете. Независимо от того, что вы пытаетесь сделать, вы не можете. Статический и динамический полиморфизм просто не смешиваются в C++.

Если ваш указатель был на B *, а не на A *, вы ожидаете, что его будет вызывать.

Смежные вопросы