为了某些全局功能
template<typename T, int count>
void func (const Obj<T>& obj) {
for (int i = 0; i < count; i++)
std::cout << obj.value << std::endl;
}
能够访问某些模板化类的私有字段value
template<typename T>
class Obj {
public:
Obj (T value);
private:
T value;
};
template<typename T>
Obj<T>::Obj (T value) : value(value) {}
我们需要声明func<T, count>
为Obj<T>
的朋友。但是,必须先声明func<T, count>
,然后才能使其成为Obj<T>
的朋友,为此,我们需要向前声明Obj<T>
。结果代码如下:
// 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;
}
但是这使gcc抱怨“在主模板的声明中无效使用template-id'func'”,所以我实际上如何为每个func<T, count>
都将Obj<T>
声明为count
的朋友?根据this answer,我只需要用此替换朋友声明
template<typename T1, int count>
friend void func (const Obj<T1>& obj);
据我所知,无论func<T1, count>
和Obj<T>
是否匹配,这都会使T1
成为T
的朋友,这是荒谬的。是否可以将func<T, count>
声明为Obj<T>
的朋友,而不能声明其他任何Obj<T1>
? (最好是将func<T, count>
的定义保持在Obj<T>
的定义之外的方式)
((我知道我可以将count
设为真实参数,但是上面的示例只是我的真实代码的简化。实际上,我正在尝试以某种方式为某些类std::basic_ostream<CharT, Traits>& operator<< (std::basic_ostream<CharT, Traits>& stream, const Obj<T>& obj)
重载Obj<T>
允许operator<<
访问Obj<T>
的私有字段。)
friend
声明必须与任何可能的前向声明以及定义(包括模板参数)都匹配。