我需要为模板化的类定义友元函数。功能有 返回类型,是类的成员类型。现在,我不能事先声明它,因为当时还不知道返回类型。像这样的东西
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 :(得分:1)
我设法使用:
在g ++上编译代码template<class T> typename A<T>::member_type fcn(typename A<T>::member_type);
(因此需要第二个'typename')
答案 1 :(得分:1)
你还需要在论证中说typename
:
template <class T>
typename A<T>::member_type fcn(typename A<T>::member_type);
// ^^^^^^^^
否则您的代码没有问题,只要所有模板定义在首次实例化之前出现。
答案 2 :(得分: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));
}
希望它有所帮助。祝你好运!
答案 3 :(得分:1)
现在这可能与其他人的答案是多余的,但这里是一个完整的,可测试的解决方案。最终函数定义是fcn
的模板特化,它将产生编译器错误,指示A<double>::x
无法从fcn<int>
访问,但A<int>::x
是 access。
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;
}