Некоторые проблемы с другом шаблона класса - PullRequest
2 голосов
/ 13 марта 2012

У нас есть два шаблона классов: A и B и шаблон функции f1 ().Например:

template< class T >
class A{};

template< class T >
class B
{
    friend class A<T>;          /* Expression 1 */
    friend void f1( B<T> &b );  /* Expression 2 */
};

template< class T >
void f1( B<T> &b ) {}

int main()
{
    A< int > a;
    B< int > b;

    f1( b );

    return 0;
}

задача 1: выражение 1 делает специализацию A с аргументом T другом специализации B с аргументом T. Но как сделать каждую специализацию Aвсе друзья специализации B?

задача 2: как определить f1 вне определения класса?код, подобный этому, выдаст ошибку:

undefined reference to `f1(B<int>&)'

задача 3: как сделать всех f1 () (которые могут получить всю специализацию B в качестве аргументов) друзьями любой специализациииз B?

Ответы [ 2 ]

3 голосов
/ 13 марта 2012

задача 1: использовать

template <typename U> friend class A; 

вместо

friend class A<T>;

проблема 2: выражение 2 объявляет друга как обычную функцию, принимающую B, а не специализацию шаблона функции. Чтобы объявить Friend специализацией для T, вам нужно, чтобы в приложении Friend было показано объявление f1 и добавлено <>, чтобы отметить, что f1 является специализацией, а не перегруженной нормальной функцией, поэтому

template< class T >
class B;
template< class T >
void f1( B<T> &b );
template< class T >
class B
{
    friend void f1<>( B<T> &b );
};

template< class T >
void f1( B<T> &b ) {}

Решение проблемы 3 представляет собой сочетание двух:

class B;
template< class T >
void f1( B<T> &b );
template< class T >
class B
{
    template <typename U> friend void f1( B<U> &b );
};
2 голосов
/ 13 марта 2012

Задача 1:

Вы действительно хотите это сделать?Вы хотите A<int> для доступа B<float>?Обычно это не так, но если вы действительно хотите:

template <typename U>
friend class A;

Проблема 2:

Проблема в том, что вы не делаете экземпляр шаблона f1 другом, а скорее вы пытаетесь сделать не шаблонную бесплатную функцию f1, которая займет B<int> вашего друга.Правильный синтаксис подружиться с конкретным экземпляром является громоздким:

template <typename T> class B;
template <typename T> void f( B<T>& );
template <typename T>
class B {
   friend void f<T>( B<T>& );
};

Задача 3:

Сделать все специализации f1 другом (опять же, вы действительно этого хотите?),Вы можете сделать тот же подход, что и для шаблона класса:

template <typename U>
friend void f1( B<U>& );

Подробнее обо всех этих здесь

...