Мне нужно определить функцию друга для шаблонного класса. Функция имеет
возвращаемый тип, который является типом члена класса. Теперь я не могу объявить это заранее, так как тип возвращаемого значения не известен в то время. Что-то вроде этого
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);
};
Как мне это сделать?
Мне удалось скомпилировать этот код на g ++, используя:
template<class T> typename A<T>::member_type fcn(typename A<T>::member_type);
(Таким образом, потребовалось второе имя типа)
Ты должен сказать typename
также в аргументе:
template <class T>
typename A<T>::member_type fcn(typename A<T>::member_type);
// ^^^^^^^^
В противном случае с вашим кодом проблем не возникнет, если появляются все определения шаблонов. до шаблон функции сначала создается.
Похоже, что в вашем конкретном примере ничего 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));
}
Надеюсь, поможет. Удачи!
Теперь это может быть излишним с ответом кого-то другого, но вот полный, тестируемый решение. Окончательное определение функции — это специализация шаблона 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;
}