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

发布于 2024-11-25 20:18:28 字数 411 浏览 6 评论 0原文

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

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 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

陈甜 2024-12-02 20:18:28

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

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 关键字在返回类型之前添加前缀。

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

上面的代码应该允许这个工作:

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

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>();
}
愁以何悠 2024-12-02 20:18:28

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

与整个模板交朋友:

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

与具体实例交朋友(即允许 f< ;int> 访问 MyClass 但不能访问 MyClass):

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

自动实例化友好的非模板function:

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

我建议您使用后者,除非该函数使用除 MyClassT 之外的其他模板参数进行参数化。

推荐阅读:重载好友运算符<<对于模板类

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

π浅易 2024-12-02 20:18:28
template <typename U> friend Client<U> initialize(.....);
template <typename U> friend Client<U> initialize(.....);
墨小墨 2024-12-02 20:18:28

您可能应该将析构函数设为公开。如果您需要将其保持私有,则需要声明另一个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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文