Объявлять функцию шаблона шаблона класса шаблона
У меня есть шаблонный класс Obj
и make_obj
. Obj
имеет один определенный конструктор, который ссылается на свой шаблонный тип для привязки к.
template <typename T>
class Obj {
private:
T& t;
Obj(T& t)
: t{t}
{ }
};
template <typename T>
Obj<T> make_obj(T& t) {
return {t};
}
Как вы можете видеть, этот конструктор является закрытым. Я хочу объявить функцию make_obj
a friend
, чтобы она могла создавать Obj
, но никто не может (кроме как с помощью copy ctor).
Я пробовал несколько объявлений друзей, включая
friend Obj make_obj(T&);
и
template <typename T1, typename T2>
friend Obj<T1> make_obj(T2&);
Последнее является менее желательной попыткой сделать все шаблонные экземпляры make_obj
друзей класса Obj
. Однако в обоих случаях я получаю ту же ошибку:
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");
^
пытается сделать make_obj("hello");
для целей.
Как я могу разрешить только make_obj
доступ к Obj
конструктору значения?
Ответы
Ответ 1
Вам нужно несколько передовых объявлений:
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);
}
живой пример
И BTW: Я не думаю, что вы действительно хотите T & t;
для переменной-члена вашего класса. Вероятно, T t;
- лучший выбор;)
Ответ 2
С синтаксисом автоматического возврата, вам нужно только переслать объявление функции, и все работает. Вот пример
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;
}
https://ideone.com/3k86gx