Was ist der Unterschied zwischen (Typ) Wert und Typ (Wert)?
-
22-07-2019 - |
Frage
Was ist der Unterschied zwischen
(type)value
und
type(value)
in C ++?
Lösung
Es gibt keinen Unterschied; pro Standard (§5.2.3):
Ein einfacher-Typ-Spezifizierer (7.1.5), gefolgt von einem geklammerten Ausdrucksliste konstruieren einen Wert des angegebenen Typs der Ausdrucksliste angegeben. Wenn die Ausdrucksliste ein einziger Ausdruck ist, die Expression der Typ Umwandlung entspricht (in Definiert, und wenn in definierte Bedeutung aufweist) mit dem entsprechenden Guss Ausdruck (5.4).
Da die Frage nach dem Unterschied zwischen type(value)
und (type)value
angegeben, gibt es absolut keinen Unterschied.
Wenn und nur wenn Sie mit einer kommagetrennten Liste von Werten zu tun haben kann es ein Unterschied sein. In diesem Fall:
Wenn der Ausdruck Liste mehr als einen einzigen Wert gibt, ist der Typ eine Klasse mit einem entsprechend deklariert Konstruktor sein (8.5, 12.1), und der Ausdruck T (x1, x2, ...) entspricht in der Tat auf die Erklärung T t (x1, x2, ...); Für einige erfundene temporäre Variable t mit dem Ergebnis, als ein R-Wert der Wert von t ist.
Wie Troubadour wies darauf hin, gibt es einige Namen von Arten, für die die type(value)
Version einfach nicht kompilieren. Zum Beispiel:
char *a = (char *)string;
kompiliert, aber:
char *a = char *(string);
nicht. Die gleiche Art mit einem anderen Namen (zum Beispiel mit einem typedef
erstellt) kann zwar funktionieren:
typedef char *char_ptr;
char *a = char_ptr(string);
Andere Tipps
Es gibt keinen Unterschied; die C ++ Standard (1998 und 2003 Ausgaben) ist über diesen Punkt klar. Versuchen Sie das folgende Programm, stellen Sie sicher, dass Sie einen Compiler verwenden, die als freie Vorschau-konform, so ist unter http://comeaucomputing.com/ tryitout / .
#include <cstdlib>
#include <string>
int main() {
int('A'); (int) 'A'; // obvious
(std::string) "abc"; // not so obvious
unsigned(a_var) = 3; // see note below
(long const&) a_var; // const or refs, which T(v) can't do
return EXIT_SUCCESS;
}
Hinweis: unsigned(a_var)
ist anders, aber eine Möglichkeit, besagt diese genauen Token etwas anderes bedeuten können. Es wird erklärt, eine Variable mit dem Namen a_var
vom Typ unsigned, und ist keine Besetzung überhaupt. (Wenn Sie mit Zeigern auf Funktionen oder Arrays vertraut sind, überlegen, wie Sie einen Pars um p
in einer Art wie void (*pf)()
oder int (*pa)[42]
verwenden.)
(Warnungen, da diese Aussagen erzeugt werden, nicht den Wert verwenden und in einem realen Programm, das mit ziemlicher Sicherheit ein Fehler war, aber alles noch funktioniert. Ich habe einfach nicht das Herz, um es zu ändern, nachdem alles Linie machen up).
Es gibt keinen Unterschied, wenn beide Würfe sind, aber manchmal ‚Typ (Wert)‘ ist kein gegossen.
Hier ist ein Beispiel von Standardentwurf N3242, Abschnitt 8.2.1:
struct S
{
S(int);
};
void foo(double a)
{
S w( int(a) ); // function declaration
S y( (int)a ); // object declaration
}
In diesem Fall ‚int (a)‘ keine gegossen wird, weil ‚a‘ kein Wert ist, ist es ein Parametername durch redundante Klammern umgeben. In dem Dokument heißt
Die Mehrdeutigkeit von der Ähnlichkeit zwischen einer Funktion Stil entstehen gegossen und eine Erklärung erwähnt in 6.8 kann auch im Kontext auftritt eine Erklärung. In diesem Zusammenhang ist die Wahl zwischen einer Funktion Erklärung mit einem redundanten Satz von Klammern um einen Parameter Name und eine Objektdeklaration mit einem funktions Casts als die initializer. Ebenso wie bei den in 6.8 erwähnten Zweideutigkeiten, die Auflösung ist jedes Konstrukt zu betrachten, die möglicherweise eine sein könnten Erklärung eine Erklärung an.
c gibt es keine type (value)
, während in C / C ++ sowohl type (value)
und (type) value
erlaubt sind.
Um die Optionen in C ++ veranschaulicht (nur eine hat eine Sicherheitsprüfung)
#include<boost/numeric/conversion/cast.hpp>
using std::cout;
using std::endl;
int main(){
float smallf = 100.1;
cout << (int)smallf << endl; // outputs 100 // c cast
cout << int(smallf) << endl; // outputs 100 // c++ constructor = c cast
cout << static_cast<int>(smallf) << endl; // outputs 100
// cout << static_cast<int&>(smallf) << endl; // not allowed
cout << reinterpret_cast<int&>(smallf) << endl; // outputs 1120416563
cout << boost::numeric_cast<int>(smallf) << endl; // outputs 100
float bigf = 1.23e12;
cout << (int)bigf << endl; // outputs -2147483648
cout << int(bigf) << endl; // outputs -2147483648
cout << static_cast<int>(bigf) << endl; // outputs -2147483648
// cout << static_cast<int&>(bigf) << endl; // not allowed
cout << reinterpret_cast<int&>(bigf) << endl; // outputs 1401893083
cout << boost::numeric_cast<int>(bigf) << endl; // throws bad numeric conversion
}