J'ai un modèle de classe Obj
et un modèle de fonction make_obj
. Obj
a un private
constructeur unique défini, qui prend une référence à son type de modèle pour se lier à.
template <typename T>
class Obj {
private:
T& t;
Obj(T& t)
: t{t}
{ }
};
template <typename T>
Obj<T> make_obj(T& t) {
return {t};
}
Ce que je veux, c'est déclarer la fonction make_obj
friend
pour qu'elle puisse créer des Obj
, mais personne d'autre ne peut (sauf via le ctor copie).
J'ai essayé plusieurs déclarations d'amis, y compris
friend Obj make_obj(T&);
et
template <typename T1, typename T2>
friend Obj<T1> make_obj(T2&);
Ce dernier étant une tentative peu souhaitable de faire toutes les instanciations de modèle de make_obj
Amis de la classe Obj
. Cependant, dans les deux cas, j'obtiens la même erreur:
error: calling a private constructor of class 'Obj<char const[6]>'
return {t};
^
note: in instantiation of function template specialization
'make_obj<const char *>' requested here
auto s = make_obj("hello");
^
essayer de faire make_obj("hello");
à des fins d'exemple.
Comment puis-je autoriser uniquement make_obj
À accéder au facteur de valeur de Obj
?
Vous avez besoin de quelques déclarations à terme:
template <typename T>
class Obj;
template <typename T>
Obj<T> make_obj(T t);
template <typename T>
class Obj {
private:
T & t;
Obj (T & t) : t(t) { }
Obj() = delete;
friend Obj make_obj<T>(T t);
};
template <typename T>
Obj<T> make_obj(T t) {
return Obj<T>(t);
}
Et BTW: Je ne pense pas que vous vouliez vraiment T & t;
pour la variable membre de votre classe. Probablement T t;
est un meilleur choix;)
Avec la syntaxe de type de retour automatique, il vous suffit de déclarer la fonction en avant et tout fonctionne. Voici un exemple
template <typename T>
auto make_obj(T t);
template <typename T>
class Obj {
private:
T & t;
Obj (T & t) : t(t) { }
Obj() = delete;
friend auto make_obj<T>(T t);
};
template <typename T>
auto make_obj(T t) {
return Obj<T>{t};
}
int main() {
make_obj(1);
return 0;
}