Wenn ich in einen Code-Schnipsel suche eine mögliche Implementierung von std::common_typeRückgabetyp von decltype wenn ternären angewandt (? :) Ausdruck
template <class ...T> struct common_type;
template <class T>
struct common_type<T> {
typedef decay_t<T> type;
};
template <class T, class U>
struct common_type<T, U> {
typedef decay_t<decltype(true ? declval<T>() : declval<U>())> type;
};
template <class T, class U, class... V>
struct common_type<T, U, V...> {
typedef common_type_t<common_type_t<T, U>, V...> type;
};
Der Teil, wie eine gemeinsame Art für zwei Template-Argument erhalten macht mich confused.Es ist eine Verwendung von ternären Operator mit declype.
Wie bekannt ist, ob der zweite oder dritte Operand zurückgegeben wird, wird durch den Wert des ersten Operanden entschieden. In diesem Snippet lautet der erste Operand wahr, was bedeutet, dass der Rückgabewert von Ausdruck immer declval<T>()
ist. Wenn es ist, was ich dachte, die keinen Sinn machen ... Deshalb habe ich den folgenden Test versucht
int iii = 2;
float fff = 3.3;
std::cout << typeid(decltype(false? std::move(iii):std::move(fff))).name() << std::endl;
std::cout << typeid(decltype(std::move(iii))).name() << std::endl;
std::cout << typeid(decltype(false ? iii : fff)).name() << std::endl;
std::cout << typeid(decltype(true ? iii : fff)).name() << std::endl;
// [02:23:37][[email protected]++_test]$ g++ -std=c++14 -g common_type.cpp
// output
// f
// i
// f
// f
mit dem laufenden Ergebnis Vergleicht man das Ergebnis, was, obwohl ich sein sollte wie folgt
int iii = 2;
float fff = 3.3;
std::cout << typeid(decltype(false ? iii : fff)).name() << std::endl; // should return f;
std::cout << typeid(decltype(true ? iii : fff)).name() << std::endl; // should return i;
Wer kann erklären, warum das Laufergebnis anders ist?
Mit anderen Worten, was ist das Ergebnis von decltype, wenn es auf einen ternären Ausdruck angewendet wird?
In Ihrem Beispielcode wird der Wert in 'iii' in den Datentyp 'float' konvertiert, da das Ergebnis von ternary der Typ" breiteste "ist. – jxh
Ich dachte, selbst wenn der zweite und der dritte Operand nicht vom selben Typ sind, wird implizit keine Konvertierung stattfinden. Weil ** (wahr? 1: 2,0) ** 1 anstelle von 1.0 zurückgibt. Laut der wundervollen Erklärung von @ T.C. habe ich verstanden, worauf es ankommt. Danke trotzdem. – ryu