您的位置:首页 > 其它

分享一次调试bug遇到的问题及解决方法

2016-11-10 10:54 477 查看

 一次调试遇上了这样的bug:

        error C2679: 二进制“=”: 没有找到接受...类型的右操作数的运算符(或没有可接受的转换)

例如:

#include<iostream>
#include<iterator>
#include<set>
#include<string>
using namespace std;
typedef set<string,string>::const_iterator CIT;
template<class T>
void show(CIT&it,set<T>&s)
{ for(it=s.begin();it!=s.end();++it)
{ cou...


网上搜了下,一位大神这么解释的:

我用VS2008、VS2010、VS2013、GCC都试了一下,确实VS2008、VS2010编译出错,但是VS2013编译成功了(我也很纳闷为什么成功,从标准库给出的原型来看程序应该是不能编译通过的)!

你把typedef set<string,string>::const_iterator CIT;改成typedef
set<string>::const_iterator CIT;就可以编译通过了!

你的问题是说完了,但我还有话说,如果你那本书上真是这样的代码,那你可以把那本书直接扔掉了,完全不值得看,误人子弟,害人害己,当然,我告诉你原因:

原罪一:

set模板类定义的原型是

template < class T,                        // set::key_type/value_type

          class Compare = less<T>,        // set::key_compare/value_compare

          class Alloc = allocator<T>      // set::allocator_type

          > class set;

这里第一个参数就是你要存储的数据的类型,第二个参数和第三个是可选的,第二个默认是less<T>,排序准则,是一种函数对象(重载了括号运算符的)其定义如下:

template <class T> struct less : binary_function <T,T,bool> {

bool operator() (const T& x, const T& y) const {return x<y;}

};

也就是说less<string>表示使用string的小于号作为排序准则(可以换成greater<string>就是按大于号排序);第三个就不说了!

所以typedef set<string,string>::const_iterator CIT;这个东西严格意义来说是不正确的,你跟搞不清楚它要做什么,string作为排序准则,究竟是大于号?小于号?我刚查了下string没有重载operator
(),所以不算函数对象;但是VS2013和G++能编译通过,我很纳闷!

原罪二:

来看看这个模板函数的定义,这明显不是面向对象的思想,是面向过程(C语言)的思维方式

template<class T>

void show(CIT&it,set<T>&s)

{

        for(it=s.begin();it!=s.end();++it)

        {

                cout<<*it<<"\t";

        }

        cout<<endl;

}

C++的做法是什么呢

template <class T>

void show(const set<T>& s)

{

        for (typename set<T>::const_iterator citer = s.begin(); citer != s.end(); ++citer)

        {

                cout << *citer << "\t";

        }

        cout << endl;

}

我来解释一下,这个函数的作用就是输出set容器内的每一个元素。明明只需要传入一个参数的,为什么会有两个?太奇怪了。

原罪三:(这部分可以商议)

再看这一段奇葩代码

const int N=5;

string s1
={"mick","bill","gate","rose","jane"};

string s2
={"张峰","秦平","李力","陆放","胡涛"};

set<string>name1;

name1.insert(s1,s1+N);

set<string>name2(s2,s2+N);

首先这里定义了两个临时数组,s1,s2,从这里看是为了使用数组特有的初始化列表(C++11标准后set也支持了),但从这个例子里看不出来这样使用的好处!

而且name1和name2的构造方式还不一样(第一个使用默认构造函数+insert成员函数,第二个则使用了特定的构造函数),很明显现在这个程序里不好解释

更合适的做法是:

set<string> name1;

name1.insert("mick");

name1.insert("bill");

name1.insert("gate");

name1.insert("rose");

name1.insert("jane");

set<string> name2;

name2.insert("张峰");

name2.insert("秦平");

name2.insert("李力");

name2.insert("陆放");

name2.insert("胡涛");

很一目了然,那么有些人可能会说如果元素很多呢,这样的代码会很难看,那么你其实应该将这些字符串放入文件,然后由程序读入,并使用insert插入到set中

原罪四:

cout<<"查找name2中大于“李力”的第一个元素。\n";

cit=name2.upper_bound("李力");

cout<<*cit<<endl;

set在英文下是按照字典顺序排序的,汉字的话,则不很确定,比如我在linux下使用G++运行的结果就是:

查找name2中大于<李力>的第一个元素。

秦平

注释:name2中顺序是:张峰 李力 秦平 胡涛 陆放(非拼音顺序)

而在windows下使用VS运行的结果则是:

查找name2中大于<李力>的第一个元素。

陆放(按照的是拼音顺序)

所以,这里就根本不该使用汉字来举例子,使用英文单词就会没有任何异议!

原罪五:

整个程序的布局、缩进、规范化都很差,一看都是业余的,或者很早以前的C++代码,我特别做了整理,看下:

#include<iostream>

#include<set>

#include<string>

using namespace std;

template <class T>

void show(const set<T>& s)

{

        for (typename set<T>::const_iterator citer = s.begin(); citer != s.end(); ++citer)

        {

                cout << *citer << "\t";

        }

        cout << endl;

}

int main()

{

        set<string> names;

        names.insert("mick");

        names.insert("bill");

        names.insert("gate");

        names.insert("rose");

        names.insert("jane");

        cout << "输出names中各个元素:" << endl;

        show(names);

        cout << "查找names中大于或等于<x-men>的第一个元素." << endl;

        set<string>::const_iterator cit = names.lower_bound("x-men");

        if (cit != names.end()) {

                cout << *cit << endl;

        } else {

                cout << "很抱歉, 没有没有找到大于或等于<x-men>的元素" << endl;

        }

        return 0;

}

1、去掉了#include <iterator>

2、重写了show模板函数

3、去掉了name2,将name1改为names

4、使用多次insert代替数组加insert

5、尽量使用endl而非"\n"

6、使用const_iterator而非iterator,因为不修改其值

7、对cit的返回值做了判断,就想程序里写的,找不到的时候能够正确的处理;原来的程序在找不到的情况下,就会挂掉

8、合理的使用空格和换行,让程序美观而有调理

如果你看得进去,那我推荐你一本好的书《C++ Primer》看看吧


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐