Mam więc funkcję z określoną sygnaturą w pliku nagłówkowym i chcę zadeklarować inną funkcję z dokładnie tą samą sygnaturą w klasie bez wpisania na klawiaturze parametry znowu i oczywiście, miejmy nadzieję, bez makra ... Funkcja elementu powinna mieć oczywiście dodatkowy ukryty parametr, wskaźnik this
(ponieważ nie jest on statyczną funkcją składową).Użycie decltype do zadeklarowania całego typu funkcji (nie wskaźnika!)
Teraz jestem zaskoczony, że następujący hack/trick działa zarówno w GCC, jak i ICC, ale nie jestem pewien, czy jest to "legalne" C++. Nie jestem szczególnie zainteresowany legalnością , jeśli jest to obsługiwane rozszerzenie, ale niestety nie chcę, aby łamało się aktualizacja wersji kompilatora, ponieważ niektórzy ludzie zdecydowali się na arbitralnie blokować tej użytecznej funkcji, ponieważ standard mówi "nie" (tego rodzaju rzeczy naprawdę mnie denerwują, jeśli mam być szczery).
Oto co mam na myśli:
// test.hpp
int func(int x) { return x; }
struct foo
{
decltype(func) fn; // <-- legal?
};
int test()
{
return foo().fn(6);
}
// then in test.cpp
int foo::fn(int x) { return x + 42; }
Ten prace (GCC i ICC), ale nie wiem, czy jest to "legalne" w standardzie. Proszę o zapewnienie, że jest to legalne i nie przestanie nagle działać w przyszłości.
(jeśli nie jest to zgodne z prawem i chcesz zgłosić to jako błąd, prosimy oznaczyć go jako sugestię, aby to legalne przedłużenie kompilator zamiast zabić go ...)
Zasadniczo, jest to taka sama jak deklarowanie int fn(int x);
w strukturze i tak to działa obecnie.
Jeśli pytasz mnie o przypadek użycia: jest to deklaracja funkcji elementu otoki dla innej wolnej funkcji, która robi coś ze wskaźnikiem this
przed przekazaniem go do funkcji bezpłatnej. Jego parametry muszą oczywiście dokładnie pasować. Ponownie, nie chcę ponownie wpisywać parametrów.
Jest to zgodne z prawem, o ile nie jest to typ zależny w szablonie klasy. –
W celu dodatkowego nadużycia można "zainicjować" go za pomocą "= 0;" i uczynić go wirtualnym –
@ JohannesSchaub-litb Ciekawe i nie na temat, ale ciekawy: co robi inicjowanie go z 0 zrobić? Wiem tylko, że możesz "zainicjować" to za pomocą = delete. – kktsuri