10

是否有一种语法可以仅将模板类的某些特化交友,或者您是否必须将所有特化与以下类交友:

template<class FooType> friend class Bar;

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

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

专业化似乎有自己的“友好”身份,因为默认情况下它们不是彼此的朋友。例如,getFoo()这里不能被从 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 专业化。

的标签描述有点有趣。)

4

1 回答 1

11

你正在寻找

friend Bar<FooType const>;

这是可以声明 s的两种方式之一。friend第一个语法声明一个类为友元:

friend Type;

whereType可以是简单类型Bar(不是模板),也可以是类模板的特定实例化,例如Baz<int>. int当然,也可以是封闭类模板或任何您喜欢的模板参数。关键是:它是一种被赋予朋友状态的单一类型。

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

template< ... > friend class ClassTemplate;

其中...是 的模板参数声明ClassTemplate。如您所见,您只需要指定模板参数列表,但该列表不会在任何地方使用。不可能将这两种语法结合起来,没有办法“部分地为友”类模板或使用 SFINAE/enable_if来启用或禁用某些友元声明。事实上,在模板参数中添加名称甚至没有多大意义,在你上面我只是写

template< class > friend class Bar;

因为FooType在这里添加并没有真正增加任何价值。

于 2013-10-23T16:22:45.353 回答