且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-12-22 19:59:33

我首先尝试在

I first tried to reproduce OP's issue with gcc HEAD 9.0.0 on wandbox.org and got:

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声明中重命名:

The fix is simple – T is already a template parameter and must be renamed in the nested friend declaration:

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,则可以选择以下解决方案:

If it is intended that friend void Class1::Func(U& x); depends on the same template parameter T like Class1 this would be the alternative solution:

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