web-dev-qa-db-fra.com

Pourquoi ne puis-je pas copier un tableau de style C dans std :: array?

J'ai ce code:

 std::array<int,16> copyarray(int input[16])
{
    std::array<int, 16> result;
    std::copy(std::begin(input), std::end(input), std::begin(result));
    return result;
}

Lorsque j'essaie de compiler ce code, j'obtiens cette erreur:

'std::begin': no matching overloaded function found 

et une erreur similaire pour std::end.

Quel est le problème et comment le résoudre?

20
mans

Dans la déclaration de paramètre, int input[16] est identique à int* input. Et lorsque vous passez l'argument tableau décroissance vers pointeur , les deux signifient que les informations sur la taille du tableau sont perdues. Et std::begin et std::end ne peut pas fonctionner avec des pointeurs.

Vous pouvez le modifier en passant par référence, qui réserve la taille du tableau.

std::array<int,16> copyarray(int (&input)[16])

Notez que vous ne pouvez transmettre que des tableaux dont la taille exacte est 16 à la fonction maintenant.

40
songyuanyao

Tout est important dit déjà, vous pouvez obtenir la fonction un peu plus flexible:

template <typename T, size_t N>
std::array<T, N> copyarray(T const (&input)[N])
{
    std::array<T, N> result;
    std::copy(std::begin(input), std::end(input), std::begin(result));
    return result;
}

Édition (tardive): il y a un inconvénient avec l'approche ci-dessus: vous devrez copier le tableau retourné lors de l'affectation, car il ne contient pas toutes les données réellement mobiles (c'est la même chose pour les tableaux bruts déjà). Vous pouvez éviter cet inconvénient en copiant directement dans le tableau cible:

template <typename T, size_t N>
void copyarray(std::array<T, N>& target, T const (&source)[N])
{
    std::copy(std::begin(source), std::end(source), std::begin(target));
}

Cela imite l'affectation target = source; si vous préférez, vous pouvez bien sûr échanger les paramètres pour que le paramètre de sortie dure en dernier.

Utilisation (telle quelle):

int source[7] = { };
std::array<int, sizeof(source)/sizeof(*source)> target;
copyarray(target, source);
34
Aconcagua

Comme indiqué précédemment, le problème ici est que les tableaux se désintègrent aux pointeurs lorsqu'ils sont passés à une fonction, ce qui signifie que la taille n'est pas préservée.

Si toutefois vous saviez qu'il y avait 16 éléments dans le tableau, vous pouvez le faire:

array<int,16> copyarray(const int input[]) {
    array<int, 16> result;
    copy_n(input, size(result), begin(result));
    return result;
}    
1
Jonathan Mee