如何制作模板类的模板功能朋友

时间:2011-07-25 16:07:39

标签: c++ templates friend

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

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

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

4 个答案:

答案 0 :(得分:4)

忽略省略号(我假设它是“一堆与问题无关的参数”),这应该有效:

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

这取决于你想要达到的目的。您可能希望与模板的单个实例化建立联系,或者您可能希望与所有实例进行交互。最后你可能真的不想成为一个模板,而只是一个非模板化的函数,由编译器在你的类模板实例化时自动生成...

与整个模板交朋友:

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

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

推荐阅读:overloading friend operator<< for template class

答案 3 :(得分:0)

你应该制作你的析构函数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;
}