How to make template function friend of template class

限于喜欢 提交于 2019-12-08 05:26:50

问题


I have a template class with private constructor and destructor:

template <typename T>
class Client
{
    private:
        Client(...) {}
        ~Client()   {}

        template <typename U>
        friend class Client<T>& initialize(...);
};


template <typename T>
Client<T> initialize(...) 
{
      Client<T> client = new Client<T>(...);
}

I'm not sure of the correct syntax for the friend. Can anybody help?


回答1:


Ignoring the ellipses (which I assume mean "a bunch of parameters that aren't relevant to the question"), this should work:

template <typename T>
class Client
{
private:
    Client() {} // Note private constructor
public:
    ~Client() {} // Note public destructor

    // Note friend template function syntax
    template<typename U>
    friend Client<U> initialize();
};


template<typename T>
Client<T> initialize() 
{
      /* ... */
}

Notice that the friend declaration is essentially the same as the function declaration but with the friend keyword prefixed before the return type.

Also, the destructor is public so that users of initialize() will be able to destruct the returned instance of Client<>. The constructor is still private so only initialize() can create instances of it.

The above code should allow this to work:

int main()
{
    Client<int> client = initialize<int>();
}



回答2:


template <typename U> friend Client<U> initialize(.....);



回答3:


It depends on what exactly you are trying to achieve. You may want to befriend a single instantiation of the template, or you might want to befriend all instantiations. Finally you might not really want to befriend a template, but just a non-templated function that is automatically generated by the compiler upon instantiation of your class template...

Befriending the whole template:

template <typename T>
class MyClass {
   template <typename U>
   friend MyClass<U> f();
};

Befriending a concrete instantiation (i.e. allowing f<int> access to MyClass<int> but not to MyClass<double>):

// Forward declarations
template <typename T>
class MyClass;
template <typename T>
MyClass<T> f();

// Definition of class template
template <typename T>
class MyClass {
   friend MyClass<T> f<T>();
};

// Definition of friend function
template <typename T>
MyClass<T> f() { ... }

Automatic instantiation of a befriended non-template function:

template <typename T>
class MyClass {
    friend MyClass<T> f() { ... } // define inline
};

I would recommend that you use the latter, unless the function is parametrized with other template parameters than the T for MyClass<T>.

Recommend reading: overloading friend operator<< for template class




回答4:


You should probably make your destructor public. If you need to keep it private you need to declare another friend function to delete the Client objects that you've created.

template <typename T>
class Client
{
    private:
        Client() {}
        ~Client() {}

        template <typename U>
        friend Client<U> *initialize();

        template <typename U>
        friend void destroy( Client<U> * );
};


template <typename T>
Client<T> *initialize() 
{
  return new Client<T>();
}

template <typename T>
void destroy( Client<T> *client )
{
  delete client;
}

int main()
{
  auto client = initialize<int>();

  destroy( client );

  return 0;
}


来源:https://stackoverflow.com/questions/6819075/how-to-make-template-function-friend-of-template-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!