模板类中用于朋友声明的其他模板参数?

问题描述 投票:0回答:1

为了某些全局功能

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>的私有字段。)

c++ templates friend
1个回答
0
投票

friend声明必须与任何可能的前向声明以及定义(包括模板参数)都匹配。

© www.soinside.com 2019 - 2024. All rights reserved.