如何将特定模板专业化的朋友?

时间:2013-10-23 16:14:19

标签: c++ templates c++11 friend

是否存在仅为某个模板类的某些特化提供信息的语法,或者您是否必须使用以下内容与所有专业相关的朋友:

template<class FooType> friend class Bar;

如果它存在,我会寻找类似的东西:

template<class FooType> friend class Bar<FooType const>;

专业化似乎有自己的“友好”身份,因为默认情况下他们不是彼此的朋友。例如,getFoo()这里不能通过const专门化派生的非const情况调用,因为它是私有的:

template<class FooType> class Bar;

template<class FooType>
class Bar<FooType const> {
public:
    Bar (std::string name) : _foo (name) { }
    FooType const * operator->() const
        { return &getFoo(); }
private:
    FooType const & getFoo() const
        { return _foo; }
private:
    FooType _foo;
};

template<class FooType>
class Bar : public Bar<FooType const> {
public:
    Bar (std::string name) : Bar<FooType const> (name) { }
    FooType * operator->()
        { return &getFoo(); }
private:
    FooType & getFoo()
        { return const_cast<FooType &>(Bar<FooType const>::getFoo()); }
};

您必须将template<class FooType> friend Bar;添加到const专门化。

(顺便说一下,的标签说明很有趣。)

1 个答案:

答案 0 :(得分:9)

您正在寻找

friend Bar<FooType const>;

这是两种方式之一,可以声明friend。第一种语法将一个类声明为朋友:

friend Type;

其中Type可以是简单类型Bar(不是模板),也可以是类模板的特定实例,例如Baz<int>。当然,int也可以是封闭类模板中的模板参数或任何您喜欢的模板参数。重点是:它是一种给予朋友状态的单一类型。

第二种语法将类模板声明为朋友:

template< ... > friend class ClassTemplate;

其中...ClassTemplate的模板参数声明。如您所见,您必须仅指定模板参数列表,但不会在任何地方使用该列表。无法将两种语法组合在一起,无法“部分地与朋友”类模板或使用SFINAE / enable_if来启用或禁用某些朋友声明。事实上,在模板参数中添加名称甚至没有多大意义,在上面我只写

template< class > friend class Bar;

因为添加FooType并没有真正添加任何有价值的东西。