2017-06-24 1 views
0

J'ai le code suivant qui copie un std::vector a dans un autre std::vector b, mais avec 2 comme index de départ. Comme les deux vecteurs ont une longueur de 4, il en résulte une écriture hors-limites. Je voudrais laisser ce code jeter une exception, mais comment puis-je faire cela? Le code ci-dessous se bloque avec une erreur de segmentation.Comment lancer une exception pour écrire hors limites avec std :: transform?

#include <vector> 
#include <iostream> 

int main() 
{ 
    std::vector<double> a = {1, 2, 3, 4}; 
    std::vector<double> b(4); 

    try 
    { 
     std::transform(a.begin(), a.begin()+4, b.begin()+2, 
       [](const double d) { return d; }); 
    } 
    catch (std::exception& e) 
    { 
     std::cout << "EXCEPTION: " << e.what() << std::endl; 
     return 1; 
    } 

    return 0; 
} 
+0

Sans rapport avec votre problème, mais si vous ne faites que copier un vecteur dans un autre, pourquoi utiliser 'std :: transform' au lieu de' std :: copy'? –

+0

L'usecase est un peu plus complexe, car je convertis des types dans la fonction lambda. J'ai rencontré ce problème et fait l'exemple le plus simple pour montrer mon problème. – Chiel

Répondre

3

std::transformassume[d_first, d_first+std::distance(first1, last1)) est valide.

Mais vous pouvez écrire votre propre algorithme, si vous ajoutez un itérateur « end » à la plage de sortie ainsi:

template <typename InputIt, typename OutputIt, typename UnaryOp> 
OutputIt safe_transform(
    InputIt first1, InputIt last1, 
    OutputIt first2, OutputIt last2, 
    UnaryOp unary_op) 
{ 
    while (first1 != last1) { 
     if (first2 == last2) 
      throw std::domain_error("Reached end of output range"); 
     *first2 = unary_op(*first1); 
     ++first1; 
     ++first2; 
    } 
    return first2; 
} 
3

transform déréférence ses itérateurs sous le capot. Il n'y a aucun moyen de l'appeler at() qui est la version à bornes contrôlées de operator[]. Vous pouvez activer les conteneurs de débogage en utilisant -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC, où libstdC++ utilisera des "itérateurs sécurisés" qui terminent le programme si vous itérez les limites.