0

我需要为模板类定义一个朋友函数。该函数的返回类型是类的成员类型。现在,我不能事先声明它,因为当时不知道返回类型。像这样的东西

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);
};

我该怎么做呢?

4

4 回答 4

1

我设法使用以下方法在 g++ 上编译该代码:

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

(因此需要第二个“类型名”)

于 2012-10-18T20:50:45.283 回答
1

typename还需要在论点中说:

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

否则你的代码没有问题,只要所有模板定义出现函数模板第一次实例化之前。

于 2012-10-18T20:51:22.163 回答
1

似乎在您的特定示例中,fcn函数中没有任何内容实际上依赖于 class 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));
}

上面示例中值得注意的是,您需要解耦交叉依赖并使您的自由函数不依赖于 class 的声明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));
}

希望能帮助到你。祝你好运!

于 2012-10-18T20:52:34.490 回答
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;
}
于 2012-10-18T20:59:29.870 回答