Функция друга в шаблонном классе требует доступа к типу члена

Мне нужно определить функцию друга для шаблонного класса. Функция имеет
возвращаемый тип, который является типом члена класса. Теперь я не могу объявить это заранее, так как тип возвращаемого значения не известен в то время. Что-то вроде этого

template<class T> class A;

//This doesn't work: error: need ‘typename’ before...
template<class T> A<T>::member_type fcn(A<T>::member_type);

//This doesn't work: error: template declaration of ‘typename...
template<class T> typename A<T>::member_type fcn(A<T>::member_type);

template<class T>
class A{
public:
typedef int member_type;
friend member_type fcn<T>(member_type);
};

Как мне это сделать?

0

Решение

Мне удалось скомпилировать этот код на g ++, используя:

template<class T> typename A<T>::member_type fcn(typename A<T>::member_type);

(Таким образом, потребовалось второе имя типа)

1

Другие решения

Ты должен сказать typename также в аргументе:

template <class T>
typename A<T>::member_type fcn(typename A<T>::member_type);
//                             ^^^^^^^^

В противном случае с вашим кодом проблем не возникнет, если появляются все определения шаблонов. до шаблон функции сначала создается.

1

Похоже, что в вашем конкретном примере ничего fcn функция на самом деле зависит от класса A, Ему даже не требуется доступ ни к каким методам / полям A, ни к общедоступным, ни к защищенным / приватным. Так что это не имеет смысла. В противном случае это имело бы какой-то смысл, но в любом случае кажется, что стоит переосмыслить вашу проблему и найти более чистое решение, которое не требует такого взлома. Если после глубоких размышлений вы все еще верите, что вам это нужно, вы можете сделать что-то вроде этого:

#include <cstdio>

template<typename T> typename T::member_type fcn(const T & v) {
return v.value_;
}

template<class T>
class A {
public:
typedef T member_type;

friend member_type fcn< A<T> >(const A<T> &);

A() : value_(1986) {}

private:
T value_;
};

int main()
{
A<int> a;
printf("The value is: %d\n", fcn(a));
}

Примечательно, что в приведенном выше примере вам необходимо удалить пару перекрестных зависимостей и сделать вашу свободную функцию не зависящей от объявления класса A, Если вы все еще чувствуете, что нуждаетесь в этом соединении, следующий код также работает:

#include <cstdio>

template <typename T>
class A;

template <typename T> typename A<T>::member_type fcn(const A<T> & v) {
return v.value_;
}

template <typename T>
class A {
public:
typedef int member_type;

friend member_type fcn<T>(const A<T> &);

A() : value_(1986) {}

private:
member_type value_;
};

int main()
{
A<void> a;
printf("The value is: %d\n", fcn(a));
}

Надеюсь, поможет. Удачи!

1

Теперь это может быть излишним с ответом кого-то другого, но вот полный, тестируемый решение. Окончательное определение функции — это специализация шаблона fcn, что приведет к ошибке компилятора, указывающей, что A<double>::x недоступен из fcn<int>, но A<int>::x является доступны.

template<class T> class A;

template <typename U>
typename A<U>::member_type fcn(typename A<U>::member_type);

template<class T>
class A {
int x;
public:
typedef int member_type;
friend typename A<T>::member_type fcn<T>(typename A<T>::member_type);
};

template<>
int fcn<int>(int x)
{
A<int> i;
A<double> d;
i.x = 0;  // permitted
d.x = 0;  // forbidden
return 0;
}
1
По вопросам рекламы [email protected]