gpt4 book ai didi

c++ - 如何将模板类 X 的模板成员函数声明为嵌套类 X::Y 的友元

转载 作者:太空狗 更新时间:2023-10-29 20:33:58 25 4
gpt4 key购买 nike

我有一个模板类。它具有模板功能。两者都采用不同的模板参数。有一个内部类需要与封闭类的模板函数成为 friend 。编译器错误比比皆是。以下玩具示例显示了我的问题。

首先,当然会编译以下内容(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的 friend (这样做可以让我解决这个问题)。 Class2是一个完全耦合到 Class1 的小助手类;它的所有特殊成员,除了析构函数和移动构造函数,都是私有(private)的或已删除的,并且Class1::Func是唯一实例化 Class2 的东西(并通过 move ctor 将其返回给 Class1 的用户)。因此,虽然将整个 Class1 加为好友并不理想。 , 它会在紧要关头完成。

提前致谢。

最佳答案

我首先尝试在 wandbox.org 上使用 gcc HEAD 9.0.0 重现 OP 的问题 并得到:

Start

prog.cc:17:23: error: declaration of template parameter 'T' shadows template parameter
17 | template <typename T> //Compiler error here.
| ^~~~~~~~
prog.cc:1:11: note: template parameter 'T' declared here
1 | template <typename T>
| ^~~~~~~~
prog.cc: In function 'int main()':
prog.cc:25:17: warning: unused variable 'c1' [-Wunused-variable]
25 | Class1<int> c1;
| ^~

1

Finish

修复很简单——T 已经是一个模板参数,必须在嵌套的 friend 声明中重命名:

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 T1> //Compiler error gone.
template <typename U>
friend void Class1<T1>::Func(U& x);
};
};

int main()
{
Class1<int> c1;
return 0;
}

上测试 wandbox.org 再次:

Start

prog.cc: In function 'int main()':
prog.cc:25:17: warning: unused variable 'c1' [-Wunused-variable]
25 | Class1<int> c1;
| ^~

0

Finish

如果 friend void Class1::Func(U& x);Class1 一样依赖于相同的模板参数 T this将是替代解决方案:

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 U>
friend void Class1::Func(U& x);
};
};

int main()
{
Class1<int> c1;
return 0;
}

wandbox.org 上测试 再次:

Start

prog.cc: In function 'int main()':
prog.cc:24:17: warning: unused variable 'c1' [-Wunused-variable]
24 | Class1<int> c1;
| ^~

0

Finish

关于c++ - 如何将模板类 X 的模板成员函数声明为嵌套类 X::Y 的友元,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51978275/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com