Comment puis-je contraindre une fonction dans une classe modélisée à renvoyer une référence à une variable membre à l'aide de auto/decltype?Utilisation de auto et decltype pour renvoyer la référence à partir de la fonction dans la classe modélisée
Voici un exemple trivial de ce que j'essaie de faire. Supposons que vous avez une classe basé sur un modèle qui stocke quelque chose dans une variable membre privée, a_
comme suit:
#include <iostream>
template <typename T>
class A
{
private:
T a_;
public:
A(T a) : a_(a) {}
// 1. Return const reference to a_
const T & get() const { return a_; }
// 2. Return non-const reference to a_
T & get() { return a_; }
};
int main(int argc, char *argv[])
{
A<int> a(3);
const auto & a1 = a.get(); // 1. Return const reference to a_
//a1 = 4; // Shouldn't compile
std::cout << "Value of a = " << a.get() << std::endl;
auto & a2 = a.get(); // 2. Return non-const reference to a_
a2 = 5;
std::cout << "Value of a = " << a.get() << std::endl;
return 0;
}
La sortie attendue/désirée est:
Value of a = 3
Value of a = 5
Mais maintenant, supposons que je veux que le compilateur pour déduire le type renvoyé par les fonctions const et non-const get()
dans A<T>
et je veux assurer que les deux appels renvoient références à a_
.
Ma meilleure estimation est actuellement:
template <typename T>
class A
{
private:
T a_;
public:
A(T a) : a_(a) {}
// 1. Return const reference to a_
const auto get() const -> std::add_lvalue_reference<const decltype(a_)>::type
{
return a_;
}
// 2. Return non-const reference to a_
auto get() -> std::add_lvalue_reference<decltype(a_)>::type
{
return a_;
}
};
mais qui ne parvient pas à compiler. La première erreur donnée par GCC est:
decltype.cpp:11:29: error: expected type-specifier
decltype.cpp:11:26: error: expected ‘;’ at end of member declaration
decltype.cpp:11:29: error: ‘add_lvalue_reference’ in namespace ‘std’ does not name a type
La motivation pour c'est En dehors de mon code exemple distillé, mais découle d'une tentative de réduire le nombre de paramètres d'un modèle prend quand un (ou plusieurs) de ces paramètres est utilisé uniquement pour spécifier un type de retour que le compilateur devrait (je pense) être capable de déduire par lui-même. Note: dans le monde réel, le type de retour de get()
n'est pas celui de a_
, mais est le type de retour de certaines fonctions f(a_)
que je sais être déductibles par le compilateur. Ainsi, mon besoin d'auto/decltype dans cet exemple.
La chose qui me déconcertant est que le compilateur peut déduire le type de retour en utilisant correctement le code quasi-identique dans une classe non basé sur un modèle:
class A
{
private:
int a_;
public:
A(int a) : a_(a) {}
// 1. Return const reference to a_
const auto get() const -> std::add_lvalue_reference<const decltype(a_)>::type
{
return a_;
}
// 2. Return non-const reference to a_
auto get() -> std::add_lvalue_reference<decltype(a_)>::type
{
return a_;
}
};
Toute aide à comprendre ce que je suis sera d'ailleurs grandement apprécié.
Détails:
Centos 6.5
gcc (GCC) 4.7.2 20121015 (Red Hat 4.7.2-5)
vous avez besoin '' typename' – Brian
const get automatique() const' Pour un type de fin-retour, vous peut seulement utiliser 'auto' avant le nom de la fonction, pas' const auto'. – dyp
@dyp Etes-vous sûr? Cela fonctionne si j'ajoute 'typename' si nécessaire. – jrok