C++ 模板类中友元声明的其他模板参数?
为了得到一些全局函数C++ 模板类中友元声明的其他模板参数?,c++,templates,friend,C++,Templates,Friend,为了得到一些全局函数 template<typename T, int count> void func (const Obj<T>& obj) { for (int i = 0; i < count; i++) std::cout << obj.value << std::endl; } 我们需要宣布func是Obj的朋友。但是func必须先声明,然后才能使其成为Obj的朋友,为此,我们需要转发declar
template<typename T, int count>
void func (const Obj<T>& obj) {
for (int i = 0; i < count; i++)
std::cout << obj.value << std::endl;
}
我们需要宣布func是Obj的朋友。但是func必须先声明,然后才能使其成为Obj的朋友,为此,我们需要转发declare Obj。生成的代码如下所示
// Forward declarations
template<typename T>
class Obj;
template<typename T, int count>
void func (const Obj<T>& obj);
// Obj<T>
template<typename T>
class Obj {
public:
Obj (T value);
template<int count>
friend void func<T, count> (const Obj<T>& obj);
private:
T value;
};
template<typename T>
Obj<T>::Obj (T value) : value(value) {} // <-- ERROR
// func<T>
template<typename T, int count>
void func (const Obj<T>& obj) {
for (int i = 0; i < count; i++)
std::cout << obj.value << std::endl;
}
据我所知,这将使func成为Obj的朋友,不管T1和T是否匹配,这是荒谬的。有没有可能宣布func是Obj的朋友而不是其他Obj?最好是保持func的定义在Obj的定义之外
我知道我可以让count成为一个实参数,但上面的例子只是我实代码的简化。实际上,我试图重载std::basic_ostream&operator友元声明必须匹配任何可能的前向声明,当然还有定义,包括模板参数
这意味着你需要
template<typename U, int count>
friend void func(const Obj<U>& obj);
或者,您可以在类定义中内联定义函数,然后不需要提供t或U模板参数:
template<int count>
friend void func(const Obj<T>& obj)
{
// Implementation...
}
在这两种情况下,您都不应该像我的评论中提到的那样真正拥有func的前向声明。您不需要这两个前向声明中的任何一个,您拥有类Obj或函数func。相反,函数的友元声明将作为其自身的转发声明。您不能在类中定义函数吗?但是,如果t和U不匹配,如何确保func不是Obj的友元?在我看来,这似乎表明func是Obj的朋友,还是我错了?这对std::basic_ostream&operator@Cubi73如果U是std::string,则声明将变为friend void functconst Obj&Obj;。是的,它将是例如Obj的朋友,但您不能将Obj对象传递给函数,所以它真的很重要吗?是的,它很重要。如果在省略额外的count参数时,我可以使funcObj obj成为obj的朋友,那么在包含count参数时,应该有一种方法可以做到这一点。
template<typename U, int count>
friend void func(const Obj<U>& obj);
Obj<int> int_obj;
Obj<float> float_obj;
func<X>(int_obj); // Will call void func<int, X>(int_obj)
func<X>(float_obj); // Will call void func<float, X>(float_obj)
template<int count>
friend void func(const Obj<T>& obj)
{
// Implementation...
}