Je crée un constructeur qui prendra une paire d'itérateurs d'entrée. Je veux la signature de la méthode d'avoir compilé Cependant, je ne peux trouver aucun exemples de ceci.
Par exemple, le constructeur de la plage de mon implémentation de stl pour qui n'a pas de compilation-heure existe-t-il un moyen d'indiquer pour garantir le appelant que je ne puisse pas modifier les données d'entrée? p> comme exemple de la façon dont je voudrais J'aime utiliser la fonction, je voudrais pouvoir passer une paire de points d'affichage Const code> Semantitique similaire à:
vecteur code> est défini comme suit: p>
const code> Garanties.
itérator_category code> /
itérator_traits <> code> ne contient rien de ce qui concerne
const code>, non plus. p>
char * code> et savoir, en fonction de la signature de fonction, que les données qu'elles pointent ne seront pas modifiées.
J'espérais que je puisse éviter de créer une paire de «indicatifs> Const» code> des pointeurs pour garantir la sémantique Const_iterator. Je suis peut-être obligé de payer la taxe de gabarit dans ce cas. P> p>
5 Réponses :
Qu'en est-il de
#include <vector> template <class T> class MyClass{ public: MyClass(typename T::const_iterator t1,typename T::const_iterator t2){ } // *EDITED*: overload for pointers (see comments) MyClass(const T* t1,const T* t2){ } }; void main(){ std::vector<int> v; std::vector<int>::const_iterator it1 = v.begin(); std::vector<int>::const_iterator it2 = v.end(); MyClass<std::vector<int> > mv(it1,it2); // with pointers: char* c1; char* c2; MyClass mc(c1,c2); }
Vous empêchez la déduction du paramètre de modèle en utilisant des types internes.
Bonne idée, mais je n'ai pas de const_iterator ici parce que je passe dans deux char * code> comme itérateurs.
Ce constructeur de vecteur reçoit ses arguments par valeur, ce qui signifie que les itérateurs de l'appelant sont copiés avant d'être utilisés dans le constructeur, ce qui signifie bien sûr que rien ne se passe sur les itérateurs de l'appelant. P>
vs p>
Dans le premier exemple, l'entrée de l'appelant pour const code> pour les arguments d'entrée seulement comptent vraiment lorsque vous passez à titre de référence. E.g. p>
void foo (int & x) code> p>
void foo (const int & x) code> p>
x code> peut être modifiée par
foo code>. Dans le deuxième exemple, ce n'est peut-être pas, car la référence est
const code>. P>
Désolé, je n'étais pas complètement clair dans ma question. Je tiens à nous assurer que les données pointant par les itérateurs sont garanties pour être traitées comme constant, non pas que les itérateurs eux-mêmes devraient être constitués.
Un const_iterator ne peut pas être utilisé pour modifier l'élément du conteneur qu'il est itération. Un itérateur ordinaire peut i> être utilisé de cette façon, même si elle est adoptée par la référence de const. (Faites simplement une copie sans const.) Les types const itérateur code> et
const_iterator code> ne sont pas les mêmes choses.
L'appelant peut simplement utiliser le modèle avec des itérateurs des constants. S'il le fait, et le compilateur ne se plaint pas, il est garanti que la fonction ne modifie pas les données. Si cela modifierait les données, l'instanciation du modèle avec un itérateur de Const entraînerait des erreurs. P>
Vous n'avez pas vraiment à la force em> l'appelant pour utiliser les itérateurs constants simplement parce que vous ne modifiez rien. P>
+1 ... et dire que je suis arrivé à tout le problème d'indiquer comment le faire!
La sémantique de l'exemple code> dataObject code> signifie que je peux passer dans des pointeurs non code> const code> et les avoir traités comme des pointeurs const code>. Je ne veux pas force i> l'appelant à utiliser
const code> itérateurs - je veux juste garantir qu'ils ne seront utilisés i> comme
const code> itérateurs.
Soit vous faites des copies défensives des données afin qu'il ne change pas (interne Cons-FR *) ou vous documentez vos exigences et activez-la avec la vie.
C'est ca le truc. J'essaie d'obtenir la signature de la fonction à la fois de documenter et de défendre, comme je peux faire avec les paramètres Const Char * CODE>.
@mskfisher: Il ne sert à rien de sortir de votre part. Pour la documentation, appelez simplement le paramètre Template Paramètre Constituteur, si vous devez, testez que la fonction compile si elle est donnée des itérateurs des constants et d'avancer.
@Unclebens: Je pense que le vôtre est la bonne réponse, pourquoi ne le postez-vous pas séparément?
Je pense que c'est exactement ce que dit qc sth. (Et il peut y avoir des gens ici, cela reviendrait une telle réponse, ce qui, pour eux, semble dire "juste ignorer la constance de la correction". :))
Je pense que ce que l'oncleben ajoute, ce qui peut-être que STH figurings va sans dire, est testé que le modèle compile si donné des itérateurs de const. Si vous examinez votre implémentation de la bibliothèque standard, vous verrez probablement qu'aucun des algorithmes standard ne vérifie explicitement qu'ils utilisent uniquement les capacités que leurs paramètres de modèle sont définis, mais vous pouvez être à peu près sûr qu'ils sont testés avec «Minimalement Capable "Itérateurs aussi près que possible. Les interfaces cochées explicites pour les modèles sont des concepts pour les concepts et les concepts sont si difficiles à obtenir que 10 ans n'étaient pas assez longs ;-).
@mskfisher Si vous avez besoin d'un const char * code>, je peux passer dans un
char * code> et il est favorisé à
const char * code>. Si vous avez besoin d'un
Char * code>, je ne peux pas passer est un
const char * code> Becuase const ne peut pas être emporté implicitement. Je pense que la plupart de l'en-tête CSTString a
Const Char * Code> pour les paramètres de source, mais l'appelant peut toujours passer dans
char * code>
@kts, c'est exactement ce que je vais, mais je veux aussi pouvoir passer dans un vecteur
aléatoire_access_itéator code> à un
INPUT_ITERATOR code> (qui sont la sémantique que je vais dans ce cas).
Ceci est facile (mais pas joli) si vous pouvez vous permettre de booster: modifier em>: Si vous voulez avoir et indiquer à ce sujet dans votre signature alors Il est courant d'exploiter le nom du paramètre Modèle: P> template<class ConstIt>
void f(ConstIt b, ConstIt e)
...
Si je comprends bien, le point de la question est de vous assurer que la fonction elle-même ne peut pas modifier la séquence. Le but n'est pas de forcer l'utilisateur à lancer manuellement des choses pour constituer des itérateurs.
Comme je l'ai dit dans mon commentaire à @sth, je veux exiger que l'itérateur puisse être utilisé i> en tant que const_iterator, comme un itérateur d'accès aléatoire peut être utilisé comme itérateur avant.
Vous pouvez simplement créer une fonction factice qui appelle votre modèle avec char * const code> pointeurs. Si votre modèle tente de modifier leurs objectifs, votre fonction factice ne compilera pas. Vous pouvez ensuite mettre ledit mannequin à l'intérieur
#ifndef ndebug code> pour l'exclure des constructions de version. P>
C'est plus comme ça. Cela me donne l'assurance du temps de compilation que je cherchais.
... Bien que pour mes besoins, je pense que vous voulez dire Const Char * Code> Pointeurs.
Est-ce le genre de chose que les concepts forcés compilateurs seraient bons? Je ne me souviens pas si la proposition a annoncé quoi que ce soit sur les exigences de Cons-Cons-ce.
Je pense que la meilleure option possible à ce stade est d'instancier explicitement la fonction à l'aide d'un
const char * code> et comptez sur celui-ci en vérification de mon compilation pour tous les autres types.