1
votes

Comment puis-je utiliser decltype pour obtenir un pointeur sans référence?

J'ai une fonction:

MyClass** array = new MyClass[100];
std::vector<MyClass*> subset = get_values_at_indices(array, indices);

J'appelle la fonction avec

auto get_values_at_indices(auto* array, Vector<int>* indices)
{
    std::vector<decltype(*array)> ret(indices->size());

    for (int i = 0; i < indices->size(); i ++)
    {
        int index = indices[i];
        ret.push_back(array[index]);
    }

    return ret;
}

Mais le compilateur voit decltype ( * array) comme MyClass * & (par opposition à MyClass * , ce que je veux) - que dois-je essayer?

(PS, j'ai essayé std :: vector ret (indices-> size ()); mais pas de dés;)

p>


3 commentaires

MyClass ** array = new MyClass [100]; - Cela n'a pas de sens. Soit MyClass * array = new MyClass [100]; ou MyClass ** array = new MyClass * [100]; . Au mieux, utilisez simplement un vecteur-de-vecteurs .


Qu'entendez-vous par "pas de dés"? Ça ne marche pas?


Désolé, nouveau MyClass * [100]. Et oui "pas de dés" signifie n'a pas fonctionné.


3 Réponses :


4
votes

* array est une expression lvalue, puis decltype donne T & , c'est-à-dire MyClass * & .

b) si la catégorie de valeur de expression est lvaleur , alors decltype donne T & ; p >

Vous pouvez exécuter std :: remove_reference code > (ou std :: decay a> selon votre intention) sur le type, par exemple

std::vector<std::remove_reference_t<decltype(*array)>> ret(indices->size());

BTW: decltype (& (** array)) devrait fonctionner, vous ' vous donnez un autre *.


0 commentaires

1
votes

Si vous êtes sûr que votre type ne peut être qu'un type arithmétique ou pointeur, vous pouvez utiliser un operator+ :

std::vector<decltype(+*array)> ret(indices->size());

C'est comme si vous essayiez de faire arithmétique sur la valeur - le résultat ne peut pas être une référence, mais est toujours le type lui-même.


0 commentaires

1
votes

Pas de réponse directe à votre question. Mais je trouve que l'utilisation de auto à cet endroit n'est pas tout à fait expressive et que cela oblige simplement à utiliser la syntaxe maladroite comme remove_reference> .

Si vous utilisez simplement le paramètre de modèle normal, vous pouvez exprimer votre intention plus facilement (et est mieux pris en charge par les compilateurs):

template <typename T>
auto get_values_at_indices(const T* array, const Vector<int>* indices)
{
    std::vector<T> ret(indices->size());

    for (int i = 0; i < indices->size(); i ++)
    {
        int index = indices[i];
        ret.push_back(array[index]);
    }

    return ret;
}

Changerait également ces Vector * à Vector & et au lieu d'utiliser le array T * array brut, je chercherais en utilisant const span & array code> (si vous avez un compilateur compatible C ++ 20, sinon augmentez ou GSL . p>


1 commentaires

Merci. Je n'ai jamais rencontré span auparavant - je vais chercher.