avec des tableaux C, il y a été le cas que simplement nommer un tableau a le même effet que l'écriture Lors de la conversion des tableaux de style C en std :: Array <> Dans un projet, je travaille sur, la grande majorité des "erreurs" apparues étaient dues à la propriété ci-dessus des tableaux C. P>
Dans tous les cas, la solution était triviale, il suffit d'ajouter Y a-t-il une raison technique que cet opérateur n'a pas pu être créé? P> & foo [0] code> pour quelque chose qui approche 50 ans. p>
.data () code>. Cependant, il m'a eu lieu qu'un opérateur de code codifié soigneusement conçu pour résoudre directement ce problème. P>
4 Réponses :
appeler données () code> est une chose à éviter. Il peut être utile d'avoir cette puissance pour (comme dans notre cas dans notre cas de migration de code ou un code optimisé en traitement des tripes), mais elle passe à l'encontre du filet de sécurité
std :: grayser code> fournit.
std::array<int, 2> a{1,2};
auto* ptr = a.data();
std::cout << ptr[2]; // boom
Std :: Array's Opérateur [] Code> n'a pas de vérification des limites. Ergo
a.data () [2] code> est aussi dangereux que
A [2] code>. (** Même si tout compilateur décent attrapera probablement cela)
Ce que j'attribue plus à la conception de la compatibilité que de bien. Pour le code critique de performance, je préférerais si opérateur [] code> a été modifié et
at_unsafe () code> a été ajouté. Cela de côté: il y a un deuxième aspect:
std :: gray code> porte le type autour de sa déclaration la rendant facilement disponible (à la fois dans la révision du code et à la recherche), le pointeur renvoyé par
Data ( ) code> perd que cela.
Le comportement que vous décrivez est implémenté dans std :: Array :: à code>. Si vous souhaitez vérifier les limites, préférez
à code> sur
opérateur [] code>.
Les données () sont introduites pour avoir une interface similaire sur plusieurs conteneurs STL. Par exemple, STD :: String and STD :: Vecteur fournit également des données () qui donne une adresse du tampon de données réel. SO STD :: L'interface Array a été conçue pour correspondre à cela. Opérateur () que vous suggérez est de manière assez différente et ne semble pas être absolument approprié. Comme ci-dessus, les commentateurs ci-dessus ont également mentionné, plus il est approprié est l'opérateur T * (), mais il ne s'agit toujours pas de la manière dont les concepteurs STL préféraient faire - ils ont introduit des données (). Pourquoi? Peut-être parce que c'est juste plus lisible. P>
" opérateur () i>" Voulez-vous dire opérateur () () code>?
Les matrices de style C sont des constructions de la taille. Vous pouvez obtenir la taille de la compilation d'un tableau via divers moyens. Cependant, lorsque la matrice se désintègre dans un pointeur, vous perdez cette information de compilation de compilation. Même si le paramètre est un type "tableau", il est toujours toujours un pointeur sans info de taille. Vous pouvez utiliser la programmation de modèles pour préserver la taille si le tableau est passé en tant que paramètre de fonction ( Cette décomposition implicite d'un tableau à un pointeur est considérée par de nombreux programmeurs C ++ pour être une faille de conception em> dans des tableaux de style C. En effet, il ne serait guère déraisonnable de dire que les conversions de pertes ne sont probablement pas des celles qui devraient être implicites. Étant donné que par contraste, C ++ 20's Y a-t-il une raison technique que cet opérateur n'a pas pu être créé? P>
blockQuote>
" pourrait strong> pas"? Non. P> Modèle
std :: gray code> est une tentative de fixer autant de défauts de matrices de style C que possible, lui permettant de se décomposer implicitement dans un pointeur serait contre-productif. P>
std :: span code > Type
fournit une conversion implicite d'un Std :: Array Code> (et des tableaux de style C, entre autres). La raison pour laquelle une telle conversion préserve les informations: pointeur ainsi que la taille. En effet, la conversion peut même préserver la nature de la compilation de cette taille. P>
Y a-t-il une bonne raison que cet opérateur n'existe pas? P> blockQuote>
Si vous voulez dire pourquoi il n'y a pas de
opérateur t * () code> pour fournir automatiquement la distribution, une (plusieurs) raisons potentielles est exactement cela - l'idée de automatique em > casting. P>
Peut-être qu'il serait commode d'avoir le code à l'aide de
std :: Array Code> pour simplement compiler correctement en utilisant
opérateur t * () code>, et loin, vous allez avec un programme qui a été construit sans erreurs. Cependant, il y a des implications à cela: p>
1) L'appel à
opérateur t * () code> est un coût d'exécution potentiel que le programmateur n'a peut-être pas souhaité, mais vient juste pour le trajet. En C ++, l'objectif est de ne payer que ce qui est souhaité et que les opérateurs de coulée s'imposent simplement s'inscrivent à l'encontre de cette idée. P>
2)
opérateur t * () code> et les opérateurs de casting en général peuvent potentiellement masquer les bugs ou Les goulots d'étranglement dans le code d'exécution, en raison de l'utilisation du programmeur. p>
Dans mon expérience, demandez à un programmeur avec une base de code jonchée d'opérateurs de casting quelles fonctions sont en cours d'appel, et plus de fois que non, ils ne sont pas sûrs de la voie de leur code, sinon ils sont tout simplement faux ( Et ne le réalisez pas avant de participer à une session de débogage et de voir tous les rebondissements et des virages à être effectués par les opérateurs de coulée apparemment innocents étant invoqués). P>
Ainsi, il est réputé que le programmeur veuille explicitement "convertir" les données en appelant une fonction telle que
data () code>, et non en utilisant un opérateur
( ) code> ils n'ont peut-être pas été au courant. p>
CASTING B> n'est jamais automatique: il faut écrire une distribution. Le problème ici est automatique conversions b>. +1.
En ce qui concerne la performance, avec la façon dont les optimiseurs modernes se comportent, c'est largement un non-problème. Godbolt.org/z/GBRHUL le montre très bien, pour la GCC et MSVC à des optimisations maximales, le la conversion est gratuite.
@Dgnuff - sauf si vous pouvez absolument garantir que l'utilisation d'un tel opérateur n'engagera aucun coût d'exécution dans aucun scénario, il s'agit d'un non-démarreur. C'est pourquoi j'ai dit un potentiel goulot d'étranglement potentiel i>. Il doit pratiquement être consexpr code> dans toutes les situations, et cela ne peut être garanti.
@Paulmckenzie que C ++ Construct (qui n'est pas 100% de temps de compilation) n'a-t-il aucune garantie de coût d'exécution?
Personnellement, je pense qu'il est plus sûr d'avoir à appeler
.data () code> que ce que nous obtenons avec des tableaux intégrés.
Y a-t-il une bonne raison que cet opérateur n'existe pas? I> - Super - un autre opérateur étant appelé au moment de l'exécution sans le programmeur en cours de conscience. Si vous remarquez, la majeure partie de la bibliothèque standard C ++ reste à l'écart des opérateurs de casting (peut-être que toute la bibliothèque standard fait). Réaliser que
std :: string code> et en général
std :: basique_string <> code> n'a pas non plus de
opérateur caractère * () code>, et plutôt, Fournissez une fonction
c_str () code>. Mon expérience est qu'un programmeur C ++ portant à plusieurs reprises leur code de code avec des opérateurs de casting ne se connaît pas dans quelles fonctions sont appelées.
@ Sepp2k Ouais, c'est l'opérateur T * Je cherche. J'ai examiné un code de code que je possède depuis des années qui l'a fait pour autre chose. Dans le temps intermédiaire, ma mémoire s'était fanée, nous utilisions
opérateur t code> dans ce contexte permettant un accès direct. La plupart du temps au moins, il fallait quelque peu sur la capacité du compilateur à déduire le type cible au moment de l'exécution. Dans 99% des cas, cela a fonctionné correctement et pour le 1% où il n'a pas eu de
.get () code> méthode pour couvrir. J'ai édité la question de manière appropriée.
Non implicitement en décomposition aux pointeurs est l'un des avantages les plus significatifs de l'utilisation de
Std :: Array Code> sur des tableaux de construction.
@ L.f. La conversion implicite n'est pas une "décroissance".
Une excellente question! (Les conversions implicites ne sont pas mauvaises, et non plus d'informations perdent des conversions.)
@Curiousguy Les matrices intégrées sont décrites aux pointeurs. Vous interrogez-vous cette phrase?
@ L.f.
std :: Array Code> n'est pas une matrice intégrée et des conversions définies par l'utilisateur ne sont rien comme l'argument décroissant. Vous interrogez-vous cette phrase?
@Cuciousguy J'ai dit "non implicitement en décomposition aux pointeurs est l'un des avantages les plus significatifs de l'utilisation de
std :: Array Code> sur des tableaux de construction." Essentiellement, cela signifie que les tableaux intégrés se décomposent implicitement aux pointeurs (c'est vrai) et que
std :: graphique code> ne décrit pas implicitement aux pointeurs (ceci est également vrai). Vous interrogez-vous cette phrase? ;-)
@ L.f. Nope ... vous êtes correct. :RÉ