I have a class template Obj
and a function template make_obj
. Obj
has a private
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 a friend
so that it can create Obj
'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 the Obj
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 to Obj
's value contructor?
Many-to-one: All instantiations of a template function may be friends to a regular non-template class. One-to-one: A template function instantiated with one set of template arguments may be a friend to one template class instantiated with the same set of template arguments.
To instantiate a template function explicitly, follow the template keyword by a declaration (not definition) for the function, with the function identifier followed by the template arguments. template float twice<float>( float original ); Template arguments may be omitted when the compiler can infer them.
The friend function is declared using the friend keyword inside the body of the class. Friend Function Syntax: class className { ... .. ... friend returnType functionName(arguments); ... .. ... }
Function templates. Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type. In C++ this can be achieved using template parameters.
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); }
live example
And BTW: I don't think you really want T & t;
for your class' member variable. Probably T t;
is a better choice ;)
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; }
https://ideone.com/3k86gx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With