类模板里加入友元函数

谁学逆向工程 2010-05-21 06:32:34
#include<iostream>
using namespace std;
#include<string>
template<typename T>
class stack
{
friend T s(T&);
friend void ss(T & ,T &);
private:
T n;
};
template<typename T>
T s(T & i)
{
return i.n;
}
template<typename T>
void ss(T & t, T & str)
{
t.n=str;
}
void main()
{
stack<string> b;
ss(b,"fff");
int PPP;cin>>PPP;
}


1>------ 已启动生成: 项目: 3, 配置: Debug Win32 ------
1>正在编译...
1>3.cpp
1>c:\users\administrator\desktop\3\3\3\3.cpp(25) : error C2664: “ss”: 不能将参数 1 从“stack<T>”转换为“std::string &”
1> with
1> [
1> T=std::string
1> ]
1>生成日志保存在“file://c:\Users\Administrator\Desktop\3\3\3\Debug\BuildLog.htm”
1>3 - 1 个错误,0 个警告
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
...全文
216 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
耍宝王 2010-05-21
  • 打赏
  • 举报
回复
不好意思编辑的时候没调整好,意思不够清晰:

请把这句话:
简单来说就是编译器并没有把
void ss(stack<T>& t, const T & str);
当成一个函数模板来对待,它只是一个根据实例的变化而变化的普通函数,也就是说

改成一下这句话来看
简单来说就是编译器并没有把stack类中的
friend void ss(stack<T>& t, const T & str);
当成一个函数模板来对待,这个声明只是声明了一个可以根据实例的变化而变化的普通函数而已,也就是说
耍宝王 2010-05-21
  • 打赏
  • 举报
回复
template<typename T> class stack;这个声明因为后面的函数模板需要stack作为参数用到

template<typename T> T s(const stack<T>&);
template<typename T> void ss(stack<T>& t, const T & str);
这两个函数模板的声明是因为,在stack类中,这两个函数是作为绑定友元函数来处理的,也就是根据<T>(函数名后的那个)的不同做一一对应的关系,因此编译器需要看见函数模板原型

如果你不使用这些声明,而在类内部直接声明为友元
friend void ss(stack<T>& t, const T & str);//此处函数名后没有<T>
则,你需要根据实际使用的不同自行定义函数实体。

简单来说就是编译器并没有把
void ss(stack<T>& t, const T & str);
当成一个函数模板来对待,它只是一个根据实例的变化而变化的普通函数,也就是说
template<typename T> void ss(stack<T> & t, const T & str);
并没有被当成友元函数来处理,因此编译时会报错
#include<iostream>
#include<string>
using namespace std;

template<typename T> class stack;
template<typename T> T s(const stack<T>&);
//template<typename T> void ss(stack<T>& t, const T & str);

template<typename T>
class stack
{
friend T s<T>(const stack<T>&);
//friend void ss<T>(stack<T>& t, const T & str);
friend void ss(stack<T>& t, const T & str);//mark
private:
T n;
};

template<typename T>
T s(const stack<T>& i)
{
return i.n;
}

template<typename T>
void ss(stack<T> & t, const T & str)
{
t.n=str;
}
void main()
{
stack<string> b;
ss<string>(b, "fff");//或者ss(b, string("fff"));
int PPP;
cin >> PPP;
}

此时报错:
test.cpp(28) : error C2248: “stack<T>::n”: 无法访问 private 成员(在“stack<T>”类中声明)
with
[
T=std::string
]
cts.cpp(16) : 参见“stack<T>::n”的声明
with
[
T=std::string
]
cts.cpp(33): 参见对正在编译的函数 模板 实例化“void ss<std::string>(stack<T> &,const T &)”的引用
with
[
T=std::string
]
此时需要定义一个普通函数才行(非函数模板)
#include<iostream>
#include<string>
using namespace std;

template<typename T> class stack;
template<typename T> T s(const stack<T>&);
//template<typename T> void ss(stack<T>& t, const T & str);

template<typename T>
class stack
{
friend T s<T>(const stack<T>&);
//friend void ss<T>(stack<T>& t, const T & str);
friend void ss(stack<T>& t, const T & str);//mark
private:
T n;
};

template<typename T>
T s(const stack<T>& i)
{
return i.n;
}
/*
template<typename T>
void ss(stack<T> & t, const T & str)
{
t.n=str;
}
*/
void ss(stack<string> & t, const string & str)//mark
{
t.n=str;
}

void main()
{
stack<string> b;
ss(b, "fff");//mark
int PPP;
cin >> PPP;
}
cattycat 2010-05-21
  • 打赏
  • 举报
回复
不声明会有链接错误,找不到s和ss函数。
谁学逆向工程 2010-05-21
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 pgplay 的回复:]
C/C++ code
template<typename T> class stack;
template<typename T> T s(const stack<T>&);
template<typename T> void ss(stack<T>& ……
[/Quote]
前面三行。为什么要声明一下
cattycat 2010-05-21
  • 打赏
  • 举报
回复
up6楼,其实不用const也可以。主要是注意friend的函数名字声明后面要加上<T>
耍宝王 2010-05-21
  • 打赏
  • 举报
回复
#include<iostream>
#include<string>
using namespace std;

template<typename T> class stack;
template<typename T> T s(const stack<T>&);
template<typename T> void ss(stack<T>& t, const T & str);//注意使用const T &

template<typename T>
class stack
{
friend T s<T>(const stack<T>&);//注意那个<T>
friend void ss<T>(stack<T>& t, const T & str);//注意那个<T>
private:
T n;
};

template<typename T>
T s(const stack<T>& i)
{
return i.n;
}

template<typename T>
void ss(stack<T> & t, const T & str)
{
t.n=str;
}
void main()
{
stack<string> b;
ss<string>(b, "fff");//或者ss(b, string("fff"));
int PPP;
cin >> PPP;
}
谁学逆向工程 2010-05-21
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 pgplay 的回复:]
LZ可以参考一下http://topic.csdn.net/u/20100424/00/c10231e7-dd72-4bee-8258-d3ddee6d839e.html这贴的3楼
[/Quote]
#include<iostream>
using namespace std;
#include<string>
template<typename T>
class stack
{
friend T s(T&);
friend void ss(stack<T> & , T &);
private:
T n;
};
template<typename T>
T s(T & i)
{
return i.n;
}
template<typename T>
void ss(stack<T> & t, T & str)
{
t.n=str;
}
void main()
{
stack<string> b;
ss(b,"fff"); int PPP;cin>>PPP;
}
红色地方是被修改过的。修改过后就剩一处错误了,就是蓝色地方
1>------ 已启动生成: 项目: 3, 配置: Debug Win32 ------
1>正在编译...
1>3.cpp
1>c:\users\administrator\desktop\3\3\3\3.cpp(25) : error C2664: “ss”: 不能将参数 2 从“const char [4]”转换为“std::string &”
1>生成日志保存在“file://c:\Users\Administrator\Desktop\3\3\3\Debug\BuildLog.htm”
1>3 - 1 个错误,0 个警告
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
耍宝王 2010-05-21
  • 打赏
  • 举报
回复
chaoliu1024 2010-05-21
  • 打赏
  • 举报
回复
1楼2楼的编译都不能通过...
2010-05-21
  • 打赏
  • 举报
回复
给个治标不治本的解决办法:
#include<iostream>
using namespace std;
#include<string>
template<typename T>
T s(T & i)
{
return i.n;
}
template<typename T, typename U>
void ss(T & t, U const & str)
{
t.n=str;
}
template<typename T>
class stack
{
friend T s<>(T&);
friend void ss<>(stack<T> & ,T const &);
private:
T n;
};
int main()
{
stack<string> b;
ss(b,string("fff"));
int PPP;cin>>PPP;
}
patricxuqi 2010-05-21
  • 打赏
  • 举报
回复
template<typename T>
void stack<T>::ss(T & t, T & str)
{
t.n=str;
}

64,701

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧