Question

J'essaie de déduire le type de retour d'une fonction et de l'utiliser comme type de retour d'une fonction membre.Pour cela, j'utilise une expression decltype.Mais toutes mes tentatives échouent si la fonction donnée prend une référence comme argument :

  • Je ne peux utiliser aucune variable membre de ma classe dans l'expression decltype, car le compilateur se plaint de l'absence de tels membres (voir func1 ci-dessous)
  • Je ne peux pas utiliser de paramètre temporaire pour le paramètre de fonction, car la fonction prend une référence et vous ne pouvez pas lier une référence lvalue non const à un paramètre temporaire (voir func2 ci-dessous)

J'ai également essayé différents opérateurs de casting pour que la référence prenne le caractère temporaire, mais rien ne semble être une expression valide.

Voici un exemple de code :

template<typename data_type, typename functor_type>
class MyClass
{
public:
    auto func1() -> decltype(functor_type::process(this->m_data)) // <--
    {
        return functor_type::process(m_data);
    }

    auto func2() -> decltype(functor_type::process(data_type{})) // <--
    {
        return functor_type::process(m_data);
    }

private:
    data_type m_data;
};

struct Functor
{
    static int process(int& a) { return a; }
};

int main()
{
    MyClass<int, Functor> m;
    int b = m.func1();
    int c = m.func2();
}
Était-ce utile?

La solution

Le premier échoue car la classe n'est pas complète dans la déclaration de fonction, comme c'est le cas dans les corps de fonctions membres, vous ne pouvez donc utiliser que les membres qui ont déjà été déclarés.

Pour le second, la bibliothèque standard fournit declval, un modèle de fonction déclaré pour renvoyer son type de paramètre de modèle.Vous pouvez l'utiliser dans des contextes non évalués lorsque vous avez besoin d'une expression d'un type particulier.

La version suivante devrait donc fonctionner :

#include <utility> // for declval

template<typename data_type, typename functor_type>
class MyClass
{
private:
    // Declare this before `func1`
    data_type m_data;

public:
    // Use the already declared member variable
    auto func1() -> decltype(functor_type::process(m_data))
    {
        return functor_type::process(m_data);
    }

    // Or use `declval` to get an expression with the required reference type
    auto func2() -> decltype(functor_type::process(std::declval<data_type&>()))
    {
        return functor_type::process(m_data);
    }
};    

Autres conseils

je pense que tu cherches std::declval<data_type&>()

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top