【发布时间】:2019-01-29 09:20:10
【问题描述】:
我有一个模板类。它具有模板功能。两者都采用不同的模板参数。有一个内部类需要与封闭类的模板函数交朋友。编译器错误比比皆是。以下玩具示例显示了我的问题。
首先,以下当然是编译(VS 2017):
template <typename T>
class Class1
{
public:
Class1() = default;
~Class1() = default;
template <typename U>
void Func(U& x) {};
};
class Class2
{
public:
Class2() = default;
~Class2() = default;
template <typename T>
template <typename U>
friend void Class1<T>::Func(U& x);
};
int main()
{
Class1<int> c1;
return 0;
}
现在让我们将Class2 移动到Class1,不做其他更改:
template <typename T>
class Class1
{
public:
Class1() = default;
~Class1() = default;
template <typename U>
void Func(U& x){};
class Class2
{
public:
Class2() = default;
~Class2() = default;
template <typename T> //Compiler error here.
template <typename U>
friend void Class1::Func(U& x);
};
};
int main()
{
Class1<int> c1;
return 0;
}
现在我得到一个编译器错误:error C3856: 'Class1<T>::Func': class is not a class template
当类嵌套时,我尝试了各种方法来声明朋友,但我无法编译它。可能没有办法做我想做的事。
请注意,我正在尝试做的事情的语义(在实际代码中,而不是这个玩具示例中)是这样的,即 Func 应该是一个成员函数。这与迭代器或运算符无关,它们当然通常是非成员函数。我在这里看到了一些类似的问题,但它们通常与迭代器或运算符有关,我还没有找到适合我的解决方案的问题。
更糟的是,考虑到我的设计,将所有Class1 声明为Class2 的朋友是可以的(这样做可以让我解决这个问题)。 Class2 是一个与Class1 完全耦合的小助手类;它的所有特殊成员,除了析构函数和移动ctor,要么是私有的,要么是已删除的,Class1::Func 是唯一实例化Class2 的东西(并通过move ctor 将其返回给Class1 的用户)。因此,虽然与整个 Class1 成为朋友并不理想,但在紧要关头还是可以的。
提前致谢。
【问题讨论】:
-
我刚刚认出
template <typename U> void Class1<T>::Func(U& x) {}是public。所以,只需删除friend的东西。 (我在开玩笑。)如果是private,你的 MCVE 会更有意义。我认为这是实际意图。 -
@scheff Ha,是的,这只是一个玩具示例,因此某些类成员的访问级别与真实代码中的不同。
标签: c++ templates inner-classes friend-function