如何为具有相同模板的模板类定义和使用友元函数?

发布于 2024-09-05 21:01:26 字数 1105 浏览 9 评论 0原文

我编写了以下代码:

#include <iostream>
using namespace std;

template <class T>
class AA
{
  T a;

public:
AA()
{
 a = 7;
}

friend void print(const AA<T> & z);
};

template <class T>
void print(const AA<T> & z)
{
    cout<<"Print: "<<z.a<<endl;
}

void main()
{
AA<int> a;
print<int>(a);
}

并收到以下错误:

error C2248: 'AA<T>::a' : cannot access private member declared in class 'AA<T>'
1>        with
1>        [
1>            T=int
1>        ]
1>        c:\users\narek\documents\visual studio 2008\projects\aaa\aaa\a.cpp(7) : see declaration of 'AA<T>::a'
1>        with
1>        [
1>            T=int
1>        ]
1>        c:\users\narek\documents\visual studio 2008\projects\aaa\aaa\a.cpp(30) : see reference to function template instantiation 'void print<int>(const AA<T> &)' being compiled
1>        with
1>        [
1>            T=int
1>        ]

出了什么问题?

PS 我使用的是 Visual Studio 2008。

I have written the following code:

#include <iostream>
using namespace std;

template <class T>
class AA
{
  T a;

public:
AA()
{
 a = 7;
}

friend void print(const AA<T> & z);
};

template <class T>
void print(const AA<T> & z)
{
    cout<<"Print: "<<z.a<<endl;
}

void main()
{
AA<int> a;
print<int>(a);
}

And getting the following error:

error C2248: 'AA<T>::a' : cannot access private member declared in class 'AA<T>'
1>        with
1>        [
1>            T=int
1>        ]
1>        c:\users\narek\documents\visual studio 2008\projects\aaa\aaa\a.cpp(7) : see declaration of 'AA<T>::a'
1>        with
1>        [
1>            T=int
1>        ]
1>        c:\users\narek\documents\visual studio 2008\projects\aaa\aaa\a.cpp(30) : see reference to function template instantiation 'void print<int>(const AA<T> &)' being compiled
1>        with
1>        [
1>            T=int
1>        ]

What's wrong?

P.S. I am using Visual Studio 2008.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

悲欢浪云 2024-09-12 21:01:27

问题是,当您执行类似操作

template<class T>
class AA {friend void print(const AA<T>&);};

并实例化 AA

AA<int> a;

时,友元声明将被实例化,就像

friend void print(const AA<int>&);

非模板函数一样!这意味着编译器不会将友元声明与您的 print 函数相匹配。

解决方案基本上是在 AA 之前声明 print 并明确告诉编译器您的友元声明正在谈论模板函数。像这样:

#include <iostream>
using namespace std;

//forward declare AA because print needs it
template<class T>
class AA;

//declare print before AA to make the friend declaration
//match with this function
template<class T>
void print(const AA<T> & z);

template <class T>
class AA
{
        //the <> is needed to make sure the compiler knows we're
        //dealing with a template function here
        friend void print<>(const AA<T> & z);

    public:
        AA() {a = 7;}

    private:
        T a;
};

//implement print
template<class T>
void print(const AA<T> & z)
{
    cout<<"Print: "<<z.a<<endl;
}

int main()
{
    AA<int> a;
    print(a);
}

如果您不在友元声明中添加 <> ,看看会发生什么是很有趣的。您将收到链接器错误。为什么?好吧,因为编译器无法将友元声明与模板 print 函数相匹配,所以它会隐式假设

void print(const AA<int>&);

存在带有原型的函数。由于我没有显式地为 print 的调用提供模板参数(这不是必需的,因为编译器应该能够推断出这一点),编译器将将此调用与声明为的函数相匹配朋友。该函数没有实现,因此出现链接器错误。

The problem is that when you do something like

template<class T>
class AA {friend void print(const AA<T>&);};

and you instantiate AA with like this

AA<int> a;

the friend declaration will be instantiated like

friend void print(const AA<int>&);

which is a non-template function! This means the compiler will not match the friend declaration with your print function.

The solution is basically to declare print before AA and explicitly tell the compiler that your friend declaration is talking about a template function. Like this:

#include <iostream>
using namespace std;

//forward declare AA because print needs it
template<class T>
class AA;

//declare print before AA to make the friend declaration
//match with this function
template<class T>
void print(const AA<T> & z);

template <class T>
class AA
{
        //the <> is needed to make sure the compiler knows we're
        //dealing with a template function here
        friend void print<>(const AA<T> & z);

    public:
        AA() {a = 7;}

    private:
        T a;
};

//implement print
template<class T>
void print(const AA<T> & z)
{
    cout<<"Print: "<<z.a<<endl;
}

int main()
{
    AA<int> a;
    print(a);
}

It is interesting to see what happens if you do not add the <> in the friend declaration. You will get a linker error. Why? Well, because the compiler cannot match the friend declaration with your template print function, it will implicitly assume a function with prototype

void print(const AA<int>&);

exists. Since I didn't explicitly provide a template parameter to the call to print (which isn't necessary because the compiler should be able to deduce this), the compiler will match this call with the function declared as friend. This function is nowhere implemented, hence the linker error.

坚持沉默 2024-09-12 21:01:27

您还可以在类定义中定义友元函数:

#include <iostream>
using namespace std;

template <class T>
class AA
{
    T a;
  public:
    AA()
    {
      a = 7;
    }

    friend void print(const AA<T> &z)
    {
      cout<<"Print: "<<z.a<<endl;
    }
};

int main()
{
  AA<int> a;
  print(a);
}

You can also define friend function inside class definition:

#include <iostream>
using namespace std;

template <class T>
class AA
{
    T a;
  public:
    AA()
    {
      a = 7;
    }

    friend void print(const AA<T> &z)
    {
      cout<<"Print: "<<z.a<<endl;
    }
};

int main()
{
  AA<int> a;
  print(a);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文