declare template friend function of template class
Solution 1
You need a few forward declarations:
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);
}
And BTW: I don't think you really want T & t;
for your class' member variable. Probably T t;
is a better choice ;)
Solution 2
With the automatic return type syntax, you only need to forward declare the function and everything works. Here is an example
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;
}
Ryan Haining
cppitertools writing python in c++ for the greater good for (auto&& i : range(1, 10, 2)) { ... } for (auto&& [i, e] : enumerate(vec)) { ... } for (auto&& n : imap([] (int i) { return i*i; }, vec)) { ... }
Updated on November 21, 2020Comments
-
Ryan Haining over 3 years
I have a class template
Obj
and a function templatemake_obj
.Obj
has aprivate
single constructor defined, which takes a reference to its templated type to bind to.template <typename T> class Obj { private: T& t; Obj(T& t) : t{t} { } }; template <typename T> Obj<T> make_obj(T& t) { return {t}; }
What I want is to declare the
make_obj
function afriend
so that it can createObj
's, but no one else can (except via the copy ctor).
I have tried several friend declaration including
friend Obj make_obj(T&);
and
template <typename T1, typename T2> friend Obj<T1> make_obj(T2&);
The latter being a less than desirable attempt at making all template instantiations of
make_obj
friends of theObj
class. However in both of these cases I get the same error: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"); ^
trying to do
make_obj("hello");
for example purposes.How can I allow only
make_obj
access toObj
's value contructor? -
David Rodríguez - dribeas almost 11 yearsYou went all the 9 yards and then dropped the ball... the friend should not be a template, but a template specialization :) [Only
make_obj<A>
needs access toObj<A>
, no need to enable access tomake_obj<Z>
!] --for the record:friend Obj<T> make_obj<T>(T t);
instead of befriending the template -
Daniel Frey almost 11 years@DavidRodríguez-dribeas You are right. I fixed the answer but not the live example to leave the "old" way as a reference. Thanks!
-
Martin Pecka about 4 yearsWow, I wouldn't say that substituting
T
return type withauto
would help, but it does! -
김선달 over 3 yearsIf the return type of a friend function relies on the class' scope type aliases, this is the only way.