如何将class模板的成员模板声明为好友?

How to declare member template of class template as friend?

给定以下代码:

template <typename T, typename D> class B;

template <typename T>
class A {
public:
  A() { }
  template <typename D>
  A(B<T, D>);
};

template <typename T, typename D>
class B {
  friend A<T>::A(B<T, D>);
  int x;
};

template <typename T>
template <typename D>
A<T>::A(B<T, D> b) {
  b.x = 42;
}

int main() {
  B<int, double> b;
  A<int> a(b);
  return 0;
}

我想将 class 模板 A<T> 的成员模板 A(B<T, D>) 声明为好友。

所以我声明,friend A<T>::A(B<T, D>);

但是我遇到了一个编译错误:

test.cc: In instantiation of ‘class B<int, double>’:
test.cc:24:18:   required from here
test.cc:13:10: error: prototype for ‘A<int>::A(B<int, double>)’ does not match any in class ‘A<int>’
   friend A<T>::A(B<T, D>);
          ^~~~
test.cc:4:7: error: candidates are: constexpr A<int>::A(A<int>&&)
 class A {
       ^
test.cc:4:7: error:                 constexpr A<int>::A(const A<int>&)
test.cc:8:3: error:                 template<class D> A<T>::A(B<T, D>) [with D = D; T = int]
   A(B<T, D>);
   ^
test.cc:6:3: error:                 A<T>::A() [with T = int]
   A() { }
   ^
test.cc: In instantiation of ‘A<T>::A(B<T, D>) [with D = double; T = int]’:
test.cc:25:13:   required from here
test.cc:20:5: error: ‘int B<int, double>::x’ is private within this context
   b.x = 42;
   ~~^
test.cc:14:7: note: declared private here
   int x;
       ^

如何解决?

错误消息的重要部分似乎是这一行:

test.cc:8:3: error:                 template<class D> A<T>::A(B<T, D>) [with D = D; T = int]

请注意模板类型 D 如何 扩展为实际类型。

这让我相信为 friend 声明添加新的模板类型可能会有所帮助:

template<typename U>
friend A<T>::A(B<T, U>);

works in my testing


稍微想了一下这背后的原因,我想是因为确实没有[=14=这样的(构造函数)函数,只有模板 template<typename D> A::A(B<T, D>).