V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
huanyingch01
V2EX  ›  C

C++ set 无法正确重载

  •  
  •   huanyingch01 · 2017-10-30 11:07:33 +08:00 · 2258 次点击
    这是一个创建于 2362 天前的主题,其中的信息可能已经有所发展或是发生改变。
    *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.

    17 条回复    2017-10-30 13:00:08 +08:00
    kkhaike
        1
    kkhaike  
       2017-10-30 11:19:44 +08:00
    1. 恕我愚昧看不懂
    2. 环境是啥
    huanyingch01
        2
    huanyingch01  
    OP
       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
        3
    xdotzv  
       2017-10-30 11:30:50 +08:00
    你在重载啥?
    流输出 operator 的重载形式应该是
    std::ostream& operator<< (std::ostream& stream, const Math::Matrix& matrix);
    kkhaike
        4
    kkhaike  
       2017-10-30 11:37:33 +08:00
    1. 看起来你是写了个可序列化的类
    2. 你可以在调试的时候,在 1 内看到 val 的类型
    justou
        5
    justou  
       2017-10-30 11:40:24 +08:00
    模板重载解析,应该把完整代码贴出来。

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

    呃,模版我都没怎么写过,默默 mark 等解答···
    huanyingch01
        10
    huanyingch01  
    OP
       2017-10-30 12:03:33 +08:00
    @lrxiao sorry 2 不是模版写错了
    huanyingch01
        11
    huanyingch01  
    OP
       2017-10-30 12:05:46 +08:00
    @kkhaike 主要是其他 std 的数据类型 map,list,deque,vector 都是对的,就 set 不对,所有实现都是一样的
    wevsty
        12
    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
        13
    limhiaoing  
       2017-10-30 12:26:05 +08:00 via iPhone
    这个需要用模板特化
    huanyingch01
        14
    huanyingch01  
    OP
       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
        15
    huanyingch01  
    OP
       2017-10-30 12:32:39 +08:00
    araraloren
        16
    araraloren  
       2017-10-30 12:46:00 +08:00
    你是想说模板实例化的规则(写法的优先级什么的,比如 1、2 )还是楼上的模板特化呢。。。
    huanyingch01
        17
    huanyingch01  
    OP
       2017-10-30 13:00:08 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1605 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 16:54 · PVG 00:54 · LAX 09:54 · JFK 12:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.