模板充当模板类的朋友

时间:2013-11-29 17:22:19

标签: c++ templates friend

如果我有模板类,例如template <typename T> class Foo,我知道可以使用相同的模板参数将模板函数声明为此类的朋友。请参阅以下代码:

#include <iostream>

template <typename T> class Foo;

template <typename U>
U bar(Foo<U>& f)
{
  return f.val_;
}

template <typename T>
class Foo {
private:
  T val_, imag;

public:
  Foo(T val) : val_(val) {}

  friend T bar<>(Foo<T>& f);
};


int main()
{
  Foo<int> foo(1);
  std::cout << bar(foo) << std::endl;
}

但是如何使用模板类的模板参数声明具有更多模板参数的模板函数成为模板类的朋友,并且只有剩余的模板参数是可变的?

详细地说我想要这样的东西:

template <typename T> class Foo;

template <typename U, typename V>
U bar(Foo<U>& f, V& v)
{
    ...
}

template <typename T>
class Foo {
private:
  T val_, imag;

public:
  Foo(T val) : val_(val) {}

  template<typename V> friend T bar<>(Foo<T>& f, V& v);
};

如果有人能帮我解决这个问题,我会很高兴。

2 个答案:

答案 0 :(得分:1)

简而言之,你不能这样做,即使是艰难似乎也是一个合乎逻辑的选择。原因如下:

如果您声明这样的朋友:template<typename V> friend T bar<>(Foo<T>& f, V& v);您实际上是指另一个函数,而不是具有两个模板参数的函数。如果您有类型Foo<int>,那么您的朋友声明会拒绝具有此定义的函数:

template < typename V>
int bar(Foo<int>& f, V& v);

这是一个完全不同的功能:

template <typename U, typename V>
U bar(Foo<U>& f, V& v);

答案 1 :(得分:1)

你的朋友声明只有一个模板参数,而bar声明本身有两个,使它们完全不同。通过向朋友声明添加第二个模板参数,我们可以使它们“等效”,尽管这是一种解决方法:

template<typename T_, typename V> friend T_ bar<>(Foo<T_>& f, V& v);