8
votes

C ++ Constructeur de base Question

Comment dois-je gérer la situation suivante: em>

J'écris ma propre classe de vecteur 2D et que vous avez le code suivant: p>

class Vector2 : public (...)
public:

   Vector2(float x, float y) {

      local_vector_storage_[0] = x;
      local_vector_storage_[1] = y;
   }

   template <typename Iterator> Vector2(Iterator begin, Iterator end) {

      ASSERT(end - begin == 2);

      resize(2);

      std::copy(begin, end, local_vector_storage_.begin());
   }

// ...
};


4 commentaires

Bonne question! Je ne vois que trois options: 1. Utilisez une gamme au lieu d'itérateurs; 2. Ajoutez un explicite (int, int) constructeur; 3. Laissez la classe AS-EST et nécessitez des flotteurs explicites. Vous pouvez également envisager d'ajouter des fonctions usine libres telles que make_vector .


En ce qui concerne votre question sur assert : vous pouvez utiliser std :: Distance à la place. Ou peut-être ne passer qu'un seul itérateur puisque vous copiez toujours un nombre constant d'éléments de toute façon.


Quel est le type de local_vector_storage_? Je suppose que c'est du vecteur mais vecteur de quoi? La classe elle-même n'est pas un modèle, le type du vecteur est probablement corrigé? D'AILLEURS. Qu'essayez-vous de faire?


Pour votre affirmation, vous pouvez utiliser std :: Distance au lieu de la soustraction, il fonctionne donc avec tous les types d'itérateurs.


4 Réponses :


6
votes

Quelque chose comme ça semble fonctionner:

template<typename T>
struct notnumeric {typedef int OK;};

template<>
struct notnumeric<int> {};

class Vector2
{
public:
   Vector2(float x, float y)
   {
   }

   template <typename Iterator>
   Vector2(Iterator begin, Iterator end, typename notnumeric<Iterator>::OK dummy = 0)
   {
   }
};


4 commentaires

Vous pouvez l'améliorer en utilisant std ::able_if :: valeur, itérateur> :: Type . Cela supprimera le paramètre "factice" et utilise le compilateur fourni (ou booster si vous êtes désespéré) Types de caractères, qui sont beaucoup plus fiables que des traits de type personnalisés. De plus, vous pourriez lancer, au lieu d'utiliser Assert.


D'accord, c'est mieux (si cela fonctionne), bien que je pense que activer_if est uniquement à booster jusqu'à ce que c ++ 0x.


@Deadmg: Comment activer_if peut-on supprimer le mannequin sur un constructeur? Je pensais que cela ne fonctionnait que sur des méthodes avec des types de retour.


@Staffan: Activer_if fonctionne chaque fois qu'une déclaration de type peut être utilisée. Dans ce cas, les arguments. Les gens utilisent simplement les types de retour le plus souvent. @Jon Hanson: C'est dans TR1 aussi.



1
votes

EDIT: Est-ce un vecteur 2D? Ou juste deux vecteurs? J'ai répondu à cela pour un vecteur 2D.

Comment dois-je gérer la situation suivante

Je pense que vous devez le supporter en supprimant le constructeur float . De lire le code, il est difficile de savoir quel type d'objet vous devriez attendre à partir de là.

de lire le code d'appel, je n'aurais aucune raison de croire que vector2 v2 (1, 5); / code> crée un vecteur de deux vecteurs, chacun avec une seule valeur.

Personnellement, je m'attendais à créer un 1x5 matrice.

si Ceci est un cas d'utilisation courante pour votre bibliothèque, envisagez un constructeur nommé : xxx

re: affirmer

L'ASSTER est une bonne vérification de la santé mentale, mais nécessite votre itérateur pour prendre en charge l'accès aléatoire (ou au moins la soustraction pour trouver la distance). Cela pourrait trop restreindre son utilisation. Pensez à utiliser un std :: Distance ou vérifiez que local_vector_storage est une taille deux ensuite.


2 commentaires

Il me semble assez clair que vecteur v2 (1, 5) construit un vecteur 2 dimensions avec une dimension avec une magnitude 1 et l'autre 5. Le local_vector_storage Les valeurs scalaires de chaque dimension pas d'autres vecteurs. Op pourrait changer ce nom, mais l'API Vector a du sens (au moins pour moi!)


@Neil: hmmm ... maintenant je suis parfaitement confus. Peut-être que tu as raison, mais pourquoi faire flotte les dimensions? Peut-être que cela compile? Affectation x et y sur le local_storage semble bizarre car le stockage réel n'est jamais redimensionné.



1
votes

Dans le cas particulier, je ne vois aucun sens de l'introduction du Vector2 (itérateur Begin, End Itérateur) Code> C'TOR du tout.

En général, je ne vois aucun sens pour imiter le STD :: vecteur code> (qui est essentiellement une enveloppe pour un tableau) lorsque la dimension de votre vector2 code> est fixe et ne change jamais. Chevauchement des cas d'utilisation entre le std :: vecteur code> et votre vector2 code> est négligeable à inexistant: std :: vecteur code> est souvent initialisé de Un autre conteneur, tandis que le vector2 code> serait initialisé à 50/50 avec deux valeurs ou avec un autre vecteur2. p>

et même si vous décidez d'aller de l'avant, la ligne: p>

ASSERT(end - begin == 2);


0 commentaires