54 votes

Pourquoi était-paire de gamme accès supprimés à partir de C++11?

Je viens de découvrir qu'à un point, le C++11 projet a std::begin/std::end des surcharges pour std::pair qui a permis le traitement d'une paire d'itérateurs comme une gamme adaptée pour une utilisation dans une gamme à base de boucle (N3126, section 20.3.5.5), mais cela a depuis été supprimé.

Personne ne sait pourquoi il a été supprimé?

Je trouve la suppression de très regrettable, car il semble qu'il n'y est pas d'autre moyen pour traiter une paire d'itérateurs comme un éventail. En effet:

  • Les règles de recherche pour début/fin dans une gamme à base de boucle pour dire que début/fin sont recherchées dans 1) que les fonctions de membres de l'objet range 2) comme gratuit fonctions associées "espaces de noms"
  • std::pair n'ont pas de début/fin des fonctions de membre du
  • Le seul espace de noms associé pour std::pair<T, U> , en général, est l'espace de noms std
  • Nous ne sommes pas autorisés à surcharger std::begin/std::end pour std::pair - mêmes
  • On ne peut pas se spécialisent std::begin/std::end pour std::pair (en raison de la spécialisation devrait être partielle et ce n'est pas permis pour les fonctions)

Est-il un autre moyen que je suis absent?

41voto

sellibitze Points 13607

Je pense que le document de 2009 "Paires ne font pas de bons plages" par Alisdair Meredith est au moins une partie de la réponse. Fondamentalement, de nombreux algorithmes de retour paires de itérateurs qui sont en fait pas garantis pour être valide plages. Il semble qu'ils ont enlevé le soutien pour l' pair<iterator,iterator> de la pour les de gamme de la boucle pour cette raison. Toutefois, la solution proposée n'a pas été pleinement adoptée.

Si vous savez que certains paire d'itérateurs représente vraiment une plage valide ensuite, vous pouvez les envelopper dans un type personnalisé qui offre begin () et end() fonctions de membre:

template<class Iter>
struct iter_pair_range : std::pair<Iter,Iter> {
    iter_pair_range(std::pair<Iter,Iter> const& x)
    : std::pair<Iter,Iter>(x)
    {}
    Iter begin() const {return this->first;}
    Iter end()   const {return this->second;}
};

template<class Iter>
inline iter_pair_range<Iter> as_range(std::pair<Iter,Iter> const& x)
{ return iter_pair_range<Iter>(x); }

int main() {
    multimap<int,int> mm;
    ...
    for (auto& p : as_range(mm.equal_range(42))) {
       ...
    }
}

(non testé)

Je suis d'accord c'est un peu de la verrue. Les fonctions qui retournent des plages valides (comme equal_range) devrait le dire en utilisant le type de retour. C'est un peu embarrassante que nous devons confirmer manuellement via quelque chose comme as_range - dessus.

6voto

Richard Hodges Points 1972

l'expansion de la réponse ci-dessus à l'aide de c++11 optimisations:

#include <utility>

template<class Iter>
struct range_t : public std::pair<Iter, Iter> {
    using pair_t = std::pair<Iter, Iter>;
    range_t(pair_t&& src)
    : std::pair<Iter, Iter>(std::forward<pair_t>(src))
    {}

    using std::pair<Iter, Iter>::first;
    using std::pair<Iter, Iter>::second;

    Iter begin() const { return first; }
    Iter end() const { return second; }
};

template<class Iter>
range_t<Iter> range(std::pair<Iter, Iter> p) {
    return range_t<Iter>(std::move(p));
}

template<class Iter>
range_t<Iter> range(Iter i1, Iter i2) {
    return range_t<Iter>(std::make_pair(std::move(i1), std::move(i2)));
}


// TEST: 

#include <iostream>
#include <set>
using namespace std;

int main() {

    multiset<int> mySet { 6,4,5,5,5,3,3,67,8,89,7,5,45,4,3 };

    cout << "similar elements: ";
    for (const auto&i : range(mySet.lower_bound(5), mySet.upper_bound(10))) {
        cout << i << ",";
    }
    cout << "\n";

    int count = 0, sum = 0;
    for (const auto& i: range(mySet.equal_range(5)))
    {
        ++count;
        sum += i;
    }
    cout << "5 appears " << count << " times\n"
    << "the sum is " << sum << "\n";

return 0;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X