C++ set 无法正确重载

2017-10-30 11:07:33 +08:00
 huanyingch01
*this << (*iter++);

// 1
template <class T>
CBuffer& operator<<(T &val);

// 2
template <class T>
CBuffer& operator<<(std::string &val);


// 调用
auto iter = val.begin();
while (iter != val.end())
{
   // static_cast<T> 不加上这个无法正确重载,原因未知
   *this << (*iter++);
}

T 为 std::string 的时候 若不显示转换 static_cast<t>,调用的是 1 ; 显示转换后, 调用的是 2.

2381 次点击
所在节点    C
17 条回复
kkhaike
2017-10-30 11:19:44 +08:00
1. 恕我愚昧看不懂
2. 环境是啥
huanyingch01
2017-10-30 11:25:24 +08:00
```
// std::map, std::vector, std::list, std::deque 都能正确调用选择重载函数
// std::set 重载还是调用不正确
template <class T>
CBuffer& operator<<(std::set<T> &val)
{
size_t uLen = val.size();
*this << uLen;

auto iter = val.begin();
while (iter != val.end())
{
// static_cast<T> 不加上这个无法正确重载,原因未知
*this << static_cast<T>(*iter++);
}
return *this;
}
```

测试环境:vs2012,vs2015
xdotzv
2017-10-30 11:30:50 +08:00
你在重载啥?
流输出 operator 的重载形式应该是
std::ostream& operator<< (std::ostream& stream, const Math::Matrix& matrix);
kkhaike
2017-10-30 11:37:33 +08:00
1. 看起来你是写了个可序列化的类
2. 你可以在调试的时候,在 1 内看到 val 的类型
justou
2017-10-30 11:40:24 +08:00
模板重载解析,应该把完整代码贴出来。

模板有点复杂,最近在看这本书 C++ Templates: The Complete Guide (2nd Edition),http://www.tmplbook.com/ , 网上有 PDF 下载
JamesMackerel
2017-10-30 11:45:05 +08:00
看看 string::begin()返回的 iter 是 iterator 还是 const_iterator。
lrxiao
2017-10-30 11:48:18 +08:00
//2 为什么要模板。。。我没搞懂你在写啥
kkhaike
2017-10-30 11:52:58 +08:00
@lrxiao 他好像想写特例,特例不是这么写的
acros
2017-10-30 12:02:48 +08:00
是说模版特化后,调用没有优先选择特化的版本?

呃,模版我都没怎么写过,默默 mark 等解答···
huanyingch01
2017-10-30 12:03:33 +08:00
@lrxiao sorry 2 不是模版写错了
huanyingch01
2017-10-30 12:05:46 +08:00
@kkhaike 主要是其他 std 的数据类型 map,list,deque,vector 都是对的,就 set 不对,所有实现都是一样的
wevsty
2017-10-30 12:17:20 +08:00
按照楼主的思路试了一下
'''
#include <set>
class CBuffer
{
public:
template <class T>
CBuffer& operator<<(T &val)
{
return *this;
}


template <class T>
CBuffer& operator<<(std::set<T> &val)
{
size_t uLen = val.size();
*this << uLen;

auto iter = val.begin();
while (iter != val.end())
{
*this << *iter++;
}
return *this;
}
};

int main()
{
std::set<int> set_int({1,2,3});
CBuffer buf;
buf << set_int;
return 0;
}
'''
vs2017,这个代码编译是没问题的。
limhiaoing
2017-10-30 12:26:05 +08:00
这个需要用模板特化
huanyingch01
2017-10-30 12:30:31 +08:00
@wevsty 是的编译没有问题。你试试把 std::set<int> set_int({1,2,3}); 改为 std::set<std::string> set_int({"1","2","3"});
然后加上
```
CBuffer& operator<<(std::string &val)
{
std::cout << "22222" << std::endl;
return *this;
}
```
理论上应该调用 CBuffer& operator<<(std::string &val)。实际调用的是 CBuffer& operator<<(T &val)
huanyingch01
2017-10-30 12:32:39 +08:00
araraloren
2017-10-30 12:46:00 +08:00
你是想说模板实例化的规则(写法的优先级什么的,比如 1、2 )还是楼上的模板特化呢。。。
huanyingch01
2017-10-30 13:00:08 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/401849

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX