Historiquement, la syntaxe des points de suspension ...
provient de C.
Cette bête complexe a été utilisé pour alimenter printf
-comme fonctions et doit être utilisé avec va_list
, va_start
etc ...
Comme vous l'avez dit, ce n'est pas sûr; mais alors C est loin d'être typé, avec ses conversions implicites de et vers void*
pour tous les types de pointeurs, sa troncature implicite d'intégrales/valeurs à virgule flottante, etc ...
Parce que C++ devait être aussi proche que possible comme une surcouche de C, il a hérité de points de suspension C.
depuis sa création, C++ pratiques ont évolué, et il y a eu une forte poussée vers frappe plus fort.
en C++ 11, ce a abouti à:
- listes initialiseur, une syntaxe sténographie pour un nombre variable de valeurs d'un type donné:
foo({1, 2, 3, 4, 5})
- modèles variadique, qui sont une bête de leurs propres et permettent d'écrire un typées
printf
par exemple
modèles VARIADIC réutiliser réellement les points de suspension ...
dans leur syntaxe, pour désigner paquets des types ou des valeurs et un opérateur Déballez:
void print(std::ostream&) {}
template <typename T, typename... Args>
void print(std::ostream& out, T const& t, Args const&... args) {
print(out << t, args...); // recursive, unless there are no args left
// (in that case, it calls the first overload
// instead of recursing.)
}
Notez les 3 utilisations différentes de ...
:
typename...
de déclarer un type variadique
Args const&...
de déclarer un paquet d'arguments
args...
pour déballer le pack dans une expression
Je suppose que les fonctions variadiques ont été ajoutées à C dans le seul but de supporter la famille de fonctions printf, qui doit être de type dangereux. Le concept d'E/S de la chaîne de format elle-même vient probablement des prédécesseurs de C comme BCPL (voir https://en.wikipedia.org/wiki/BCPL). En C++ moderne, il n'est pas nécessaire d'introduire des fonctions variées de type sécurité, car nous avons de toute façon des constructions de langage supérieures, surtout depuis C++ 11. Malheureusement, je n'ai aucune référence pour mes suppositions. Il serait intéressant de poser cette question à Bjarne Stroustrup lui-même. –
Vous pouvez faire 'void foo (double *)' et l'appeler par 'foo ((double []) {1,2,3,4,5})'. Besoin d'extension GNU C++. – user3528438
Cette fonctionnalité n'est-elle pas trop anecdotique pour être incorporée dans un langage déjà sur-affiné? Alors vous devriez aussi réclamer 'void foo (double ..., int ..., double ...)' et similaire. –