Jakie są powody istnienia std::decay
? W jakich sytuacjach przydatne jest std::decay
?Co to jest std :: decay i kiedy powinno się go używać?
Odpowiedz
< żart > Jest to oczywiście używane do rozpadu radioaktywnego std::atomic
typów do nieradioaktywnych. </żart >
N2609 jest papier, który zaproponował std::decay
. Papier wyjaśnia:
Mówiąc najprościej,
decay<T>::type
jest tożsamość typu transformacja wyjątkiem jeśli T jest typem tablicą lub odwołaniem do rodzaju funkcji. W tych przypadkach ,decay<T>::type
daje odpowiednio wskaźnik lub wskaźnik do funkcji, .
motywującą przykładem jest C++ 03 std::make_pair
:
template <class T1, class T2>
inline pair<T1,T2> make_pair(T1 x, T2 y)
{
return pair<T1,T2>(x, y);
}
który przyjął swoje parametry przez wartość, aby literały łańcuchowe działa:
std::pair<std::string, int> p = make_pair("foo", 0);
Jeśli akceptowane swoje parametry przez odniesienie, następnie T1
zostanie wydedukowane jako typ tablicowy, a następnie skonstruowanie modelu pair<T1, T2>
będzie źle sformułowane.
Ale oczywiście prowadzi to do znacznej nieefektywności. Stąd potrzeba decay
, aby zastosować zestaw transformacji, który występuje, gdy występuje wartość pass-by-value, co pozwala uzyskać efektywność przyjmowania parametrów przez odniesienie, ale nadal uzyskać transformacje typu potrzebne do pracy kodu z literałami łańcuchowymi , typy macierzy, typy funkcyjne i podobne artykuły:
template <class T1, class T2>
inline pair< typename decay<T1>::type, typename decay<T2>::type >
make_pair(T1&& x, T2&& y)
{
return pair< typename decay<T1>::type,
typename decay<T2>::type >(std::forward<T1>(x),
std::forward<T2>(y));
}
Uwaga: to nie jest rzeczywiste C++ 11 make_pair
realizacja - C++ 11 make_pair
rozpakowuje również std::reference_wrapper
s.
W przypadku funkcji szablonu, które pobierają parametry typu szablonu, często mają uniwersalne parametry. Parametry uniwersalne są prawie zawsze referencjami tego samego rodzaju. Są także niezmiennie wykwalifikowani. Jako takie, większość cech typu nie działają na nich, jak można się spodziewać:
template<class T>
void func(T&& param) {
if (std::is_same<T,int>::value)
std::cout << "param is an int\n";
else
std::cout << "param is not an int\n";
}
int main() {
int three = 3;
func(three); //prints "param is not an int"!!!!
}
http://coliru.stacked-crooked.com/a/24476e60bd906bed
Rozwiązaniem tego problemu jest użycie std::decay
:
template<class T>
void func(T&& param) {
if (std::is_same<typename std::decay<T>::type,int>::value)
std::cout << "param is an int\n";
else
std::cout << "param is not an int\n";
}
Nie jestem z tego zadowolony. "Zepsucie" jest bardzo agresywne, np. jeśli zastosowane do odniesienia do tablica daje wskaźnik.Zwykle jest zbyt agresywny dla tego rodzaju IMHO metaprogramowania – dyp
@dyp, co jest mniej "agresywne" to? Jakie są alternatywy? –
@SergeRogatch W przypadku "parametrów uniwersalnych"/odniesień uniwersalnych/odniesień do przekazywania, po prostu 'remove_const_t
- 1. Co to jest metoda Javascript CollectGarbage()? Kiedy i dlaczego powinno się go używać?
- 2. Co to jest indeks pełnotekstowy i kiedy powinienem go używać?
- 3. Co to jest uint_fast32_t i dlaczego powinno się go używać zamiast zwykłych int i uint32_t?
- 4. Co to jest Manifest w Scali i kiedy go potrzebujesz?
- 5. co to jest Request.InputStream i kiedy go użyć?
- 6. Co to jest bajt datatype i kiedy powinienem go użyć?
- 7. Co to jest SAPI i kiedy go użyjesz?
- 8. Co to jest __declspec i kiedy należy go użyć?
- 9. Co to jest Ninject i kiedy go używasz?
- 10. co to jest MVVM i czy powinniśmy go używać?
- 11. Co to jest pyximport i jak mam go używać?
- 12. Co to jest NHibernate i dlaczego powinienem go używać?
- 13. Co to jest funkcja "zewnętrzna inline" i kiedy używać?
- 14. Co to jest std :: safe_string?
- 15. Co to jest "zadanie" (proces potomny) w systemie Windows i kiedy go używać?
- 16. Co to jest typ złożony w strukturze encji i kiedy go używać?
- 17. co to jest "tryb ścisły" i jak się go używa?
- 18. Co to jest sekwencja (baza danych)? Kiedy będziemy go potrzebować?
- 19. C# USING keyword - kiedy i kiedy go nie używać?
- 20. Kiedy i jak używać std :: locale :: messages?
- 21. Co to jest err. (* Os.PathError) w Go?
- 22. Kiedy używać zwrotu i co dzieje się z zwracanymi danymi?
- 23. Co to jest | i używa się operatorów?
- 24. Co to jest usługa serwisowa i kiedy jej potrzebuję?
- 25. Co to jest wyrażenie regularne MM/DD/RRRR i jak używać go w php?
- 26. Kiedy używać viewDidLoad i kiedy używać awakeFromNib
- 27. Co to jest NPM i dlaczego go potrzebuję?
- 28. Co to jest el/element? Jak tego używać? I dlaczego?
- 29. Co to są przejściowe atrybuty factory_girl? Dlaczego miałbym go używać?
- 30. Kiedy używać node.js i kiedy używać ajax?
Jest używany w standardowej bibliotece np. podczas przekazywania argumentów do wątku. Te muszą być * przechowywane *, według wartości, więc nie można przechowywać np. tablice. Zamiast tego zapisywany jest wskaźnik i tak dalej. Jest to także metafunkcja, która naśladuje korekty typu parametru funkcji. – dyp
'decay_t' jest ładną kombinacją, aby zobaczyć, co 'auto' wydedukuje. –
[meta.trans.other] states: To zachowanie jest podobne do [...= Kilka] konwersje stosowane przy lwartością ekspresja stosowane jako rvalue, ale paski również CV zakwalifikowanych do typów klas ** aby ściślej modelowania przez wartość argumentu przechodzącej ** „. – dyp