W tym kontekście ostrzeżenie, że funkcja jest ukryta, informuje nas, że funkcja składowa w klasie pochodnej ma tę samą nazwę, ale inną sygnaturę niż funkcja w klasie bazowej. Rozważmy:
struct Base
{
void foo(int) {}
void bar(int) {}
};
struct Derived: Base
{
void bar(int, int) {}
};
int main()
{
Derived d;
d.foo(1);
d.bar(1); // will not compile: Base::bar is hidden by Derived::bar
}
W tym przykładzie, intencją mogło dodać dodatkową funkcję o nazwie „bar”, ale wynik jest, że kompilator zatrzymuje poszukuje nowych zakresów z nazwą funkcjonuje bar raz znajdzie zakresu z funkcja o nazwie bar. Zatem bar (int) jest ukryty przez pasek (int, int) (lub dowolny inny pasek z niezgodną sygnaturą). (Lub w przypadku nie wirtualnym, nawet jeśli funkcje pasują do siebie).
W tym kodzie Graznaraka, Baza :: Func jest ukryta w każdej sytuacji, w której Derived jest tworzone dla dowolnej wartości T, która nie jest zmienna (lub zmienna) const).
Graznarak pyta o prawidłowe zachowanie. Poprawny przed wygenerowanym kodem nie ma znaczenia Wyprowadzenie :: Func() zostaje wywołane.
Ale to pozostawia pytanie: Czy ostrzeżenie jest właściwe. Standard nie ma odpowiedzi. Nigdy nie wyraża opinii, czy należy generować ostrzeżenie. To, czy ostrzec przed konkretnymi problemami, czy nie, jest zawsze subiektywne, a kompilatorzy mogą się wyróżnić, wykazując dobrą ocenę w tym zakresie.
Czy Twój kompilator powinien ostrzegać przed tą sytuacją? Można sobie wyobrazić, że napisany kod robi to, co prawdopodobnie jest zamierzone. Ale istnienie szablonu sugeruje, że będzie on tworzony na więcej niż jednym typie (w przeciwnym razie, dlaczego tworzy szablon) i dla każdego innego typu, będzie się ukrywać. Można więc argumentować, że ostrzeżenie powinno zostać udzielone wraz z utworzeniem wyprowadzonego szablonu. Można jednak argumentować, że ostrzeżenie nie powinno nastąpić, dopóki nie zostanie określona instancja typu bez funkcji float.
Argumentacja za pierwszym jest taka, że ostrzeżenie nastąpi wcześniej i prawdopodobnie zostanie wykryte przez programistę, który pisze problematyczny kod. Argumentowanie za późniejsze jest takie, że dopóki nie zostanie utworzony typ nie-float, nie ma żadnej podejrzanej sytuacji, o której należy ostrzec.
Co jest nie tak z ostrzeżeniem na temat poprawnego kodu, który może nie być zgodny z oczekiwaniami? Na przykład 'if (b = true)' zwykle powoduje ostrzeżenie. – chris
Nie sądzę, że powinien generować ostrzeżenie w ogóle - nie ma nic złego w kodzie. Nigdy nie widziałem tego typu rzeczy (klasa pochodna korzystająca z funkcji szablonów), spowodowało, że pomyślałem ciężko (ouch) – pm100
Mam wrażenie, że faktycznie ukrywa ona funkcję w Base, ponieważ jeśli spróbujesz to zrobić: Base * b = new Pochodzi(); w twoim głównym przypadku wystąpi błąd kompilacji: błąd C2259: "Pochodny ": nie można utworzyć instancji klasy abstrakcyjnej 1> z powodu następujących elementów: 1> 'void Base :: Func (float)': jest abstrakcyjne to wygląda dla mnie podejrzanie. –
RedOctober