繁体   English   中英

如何使模板函数成为模板类的朋友

[英]How to make template function friend of template class

我有一个带有私有构造函数和析构函数的模板类:

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>(...);
}

我不确定朋友的语法正确。 有人可以帮忙吗?

忽略省略号(我假设它的意思是“与问题无关的一堆参数”),这应该可以工作:

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() 
{
      /* ... */
}

请注意,friend声明与函数声明本质上相同,但是在返回类型之前加有friend关键字前缀。

而且,析构函数是公共的,因此initialize()用户将能够破坏所返回的Client<>实例。 构造函数仍然是私有的,因此只有initialize()可以创建它的实例。

上面的代码应允许它工作:

int main()
{
    Client<int> client = initialize<int>();
}
template <typename U> friend Client<U> initialize(.....);

这取决于您要实现的目标。 您可能希望与模板的一个实例化成为朋友,或者与所有实例化成为朋友。 最后,您可能真的不想成为模板的朋友,而只是一个非模板函数,该函数是在实例化类模板时由编译器自动生成的...

与整个模板成为朋友:

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

结识具体的实例化(例如,允许f<int>访问MyClass<int>但不允许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() { ... }

友善的非模板功能的自动实例化:

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

我建议您使用后者,除非该函数使用MyClass<T>T以外的其他模板参数进行参数化。

推荐阅读: 对于模板类,重载friend operator <<

您可能应该将销毁者public 如果需要将其保持private ,则需要声明另一个friend函数来删除已创建的Client对象。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM