簡體   English   中英

使所有派生的模板類與C ++中的其他類成為朋友

[英]Make all derived template classes friend of other class in C++

假設我必須遵循以下層次結構:

template<class T> class Base {
protected:
    T container;
};

template<class T> class Derived1 : public Base<T> {
public:
    void f1() {
        /* Does stuff with Base<T>::container */
    }
};

template<class T> class Derived2 : public Base<T> {
public:
    void f2() {
        /* Does stuff with Base<T>::container */
    }
};

現在,我想要一個獨立的類(不是從Base派生的),該類可以直接從Base或任何派生類訪問Base<T>::container 我閱讀了有關模板朋友類的文章 ,這似乎是解決我的問題的方法,但是我還無法弄清楚語法。 我正在尋找類似的東西:

template<class T> class Foo{
    template<T> friend class Base<T>; // <-- this does not work
public:
    size_t bar(const Base<T> &b) const{
        return b.container.size();
    }
};

Derived1<std::vector<int> > d;
d.f1();
Foo<std::vector<int> > foo;
size_t s = foo.bar()

朋友類行導致error: specialization of 'template<class T> class Base' must appear at namespace scope template<T> friend class Base<T> ,並且成員變量container仍然不可訪問。

幾個問題:

就像在定義類模板時不要在類名后放置<T>

template <class T> class X<T> { ... }; // WRONG
template <class T> class X { ... };    // RIGHT

在聲明類模板時,無論是在前向聲明還是在朋友聲明中,都不應將其放在類名之后:

template <class T> class X<T>; // WRONG
template <class T> class X;    // RIGHT - declares the template exists
template <class T> friend class X<T>; // WRONG
template <class T> friend class X;    // RIGHT - says all specializations of X are friends

(除非您要創建類模板的部分專業化。例如,如果已經聲明了類模板X ,則template <class T> class X<T*> { ... };定義了將被使用的部分專業化當template參數為指針時)。

而且您的朋友聲明向后:它需要與非公共成員一起出現在類中,並命名允許使用這些成員的其他類。 (如果以其他方式起作用,那么任何新類都可以在未經擁有類許可的情況下訪問任何其他類的私有成員和受保護成員!)

因此,您需要:

template <class T> class Foo;

template<class T> class Base {
    template <class U> friend class Foo;
protected:
    T container;
};

有時不需要Foo的前向聲明,但是我認為它使事情變得更清楚,並且當名稱空間,嵌套類等開始變得更加復雜時,它可以避免麻煩。

只有Base可以說Foo是它的朋友。

template<typename T> friend class Foo; // every Foo<T> is a friend of Base

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM