#include <iostream>
using namespace std;
template <class X, class Y>
Y big(X a, Y b)
{
if (a > b)
return (a);
else return (b);
}
int main()
{
cout << big(32.8, 9);
}
Tutaj używam szablonów w CPP, więc kiedy big
wywołuję funkcję z pominięciem argumentów double
i int
typu, chcę uzyskać odpowiedź zwrotną, która jest double
. Wpisz tutaj, zwraca 32
zamiast 32.8
.
Jak uzyskać pożądaną wydajność? Jak napisać odpowiedni typ zwracanej big
funkcji?
c++
function
templates
return-type
function-templates
Rakshanda Meshram
źródło
źródło
std::max
jest wdrażany. Zwracany typ funkcji musi być znany w czasie kompilacji w C ++. Dlatego nie można mieć tego typu zwrotu zależnego od wartości środowiska wykonawczego parametrów. Dlatego dla takiej funkcji potrzebne są oba parametry, aby mieć ten sam typ (tj. Mieć typ X, ale nie Y).Odpowiedzi:
Funkcja może mieć tylko jeden typ zwracany, który musi być znany w czasie kompilacji. Można jednak użyć
std::common_type
, aby zwrócić typ, dla którego oba parametry mogą być konwertowane implicite.To by było
I aby sprawdzić, czy faktycznie zwraca a
double
po przejściuint
i adouble
możemy zrobić:Które wydruki
PS:
std::common_type
może korzystać z trójskładnikowego operatora za sceną i jako takie rozwiązanie nie różni się niczym od innych odpowiedzi (auto
+ trójskładnikowe). Prawdziwą siłąstd::common_type
jest to, że akceptuje dowolną liczbę parametrów.źródło
Typ zwracany musi zostać określony w czasie kompilacji. Możesz użyć końcowego powrotu z operatorem warunkowym , jeśli jesteś ograniczony do c ++ 11 .
Zobacz na żywo
Jeśli jednak masz dostęp do c ++ 14 lub wyższej,
auto
wystarczy, że kompilator wydedukuje odpowiedni typ, jeśli użyjesz go razem z operatorem warunkowym w następujący sposób:Zobacz na żywo
źródło
const
).Oznaczając typ zwrotu jako
Y
i przekazującint
jako drugi parametr, wyraźnie wskazałeś, żeY
jest toint
. Nie ma tu niespodzianek.Spowoduje to wydrukowanie wszystkich czterech poprawnych wartości na ekranie.
https://godbolt.org/z/fyGsmo
Jedną rzeczą, na którą należy zwrócić uwagę, jest to, że będzie to działać tylko dla typów, które można porównywać ze sobą, tj. Kompilator niejawnie przekonwertuje jeden typ na drugi dla porównania.
WAŻNE : parametry należy traktować jako odniesienie, aby uniknąć nieokreślonego zachowania. Ma to związek z typem zwrotu, którego uparcie się trzymam.
decltype(auto)
może zwracać odniesienia do typów. Jeśli zwrócisz coś lokalnego do funkcji (liczą się argumenty), otrzymasz niezdefiniowane zachowanie.źródło
Prawdopodobnie nie jest to właściwe rozwiązanie dla Twojej precyzyjnej sytuacji - inne odpowiedzi prawdopodobnie będą znacznie bliżej tego, czego chcesz.
Jeśli jednak z jakiegoś powodu naprawdę musisz zwracać całkowicie różne typy w środowisku wykonawczym, poprawnym rozwiązaniem (od wersji c ++ 17 ) jest użycie
std::variant
unii, która jest rodzajem unii bezpiecznej dla typu.Zauważ, że wtedy na dzwoniącym spoczywa ciężar radzenia sobie ze zwróconą wartością, najprawdopodobniej za pomocą
std::visit
itp.źródło
Zwraca int, ponieważ Y jest int i rzuca na niego 32.8. Gdy nazwiesz dużą, 32,82 jest liczbą zmiennoprzecinkową, ale 8 jest liczbą całkowitą, a typem funkcji jest Y, która również jest liczbą całkowitą.
Naprawdę nie możesz tego naprawić, ponieważ musisz wiedzieć w czasie wykonywania, które typy dużych zwrotów, więc ułóż aib typu tego samego typu:
źródło