Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

declare template friend function of template class

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?

like image 463
Ryan Haining Avatar asked Sep 13 '13 18:09

Ryan Haining


People also ask

Can we declare a template function as the friend of the class?

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.

How do you declare a template function?

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.

How do you declare a friend function?

The friend function is declared using the friend keyword inside the body of the class. Friend Function Syntax: class className { ... .. ... friend returnType functionName(arguments); ... .. ... }

What is template class and template function?

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.


2 Answers

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 ;)

like image 188
Daniel Frey Avatar answered Oct 15 '22 00:10

Daniel Frey


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

like image 31
Curious Avatar answered Oct 15 '22 00:10

Curious