编程百科全书

在这里,相信会找到令你尖叫的文章!

导航

单参函数前面加上explicit描述

前两天,写到一个unsigned int 打印到ostringstream,编译居然报错,出错的地方如下:

std::ostringstream & operator<< (std::ostringstream &ostr,const TEST_PET_ID &info)

{

        //test_uin_是一个unsigned int

        //下面这一行报错,

    ostr<< info.test_uin_;

……

}

由于我使用了STLport,错误信息被输出成很长,问了问周围的同事,发现其他几个人也遇到了,有几个人用在前面增加打印一个” ”规避了这个编译错误。不想偷懒规避,仔细看了看错误信息,错误ID是C2666,如下:

h:\courage\construct.test\construct.test\construct.test.cpp(19) : error C2666: 'operator <<' : 18 overloads have similar conversions

1>        h:\havefun\stlport\stlport.5.2.1\stlport\stl\_ostream.h(130): could be 'stlp_std::basic_ostream<_CharT,_Traits>

&stlp_std::basic_ostream<_CharT,_Traits>::operator <<(unsigned int)'

.. .. .. ..

1>        h:\courage\construct.test\construct.test\construct.test.cpp(17): or 'stlp_std::ostringstream &operator <<(stlp_std::ostringstream &,const TEST_QQ_UIN &)'

1>        while trying to match the argument list '(stlp_std::ostringstream, const unsigned int)'

MSDN错误信息和检查错误提示,发现是编译器无法抉择是使用,unsigned int 的输出到ostringstream的函数还是使用TEST_QQ_UIN结构的输出到ostringstream的函数。看了一下TEST_QQ_UIN的结构,发现了问题所在。

把错误的代码提炼出来,让大家容易看到问题所在:

#include <stdio.h>

#include <sstream>

struct TEST_QQ_UIN

{

    //在构造函数前面增加explicit,就正确了。

    TEST_QQ_UIN(unsigned int qq_uin):

        qq_uin_(qq_uin)

    {

    }

    ~TEST_QQ_UIN()

    {

    }

    unsigned int    qq_uin_;

};

std::ostringstream & operator<< (std::ostringstream &ostr,const TEST_QQ_UIN &info)

{

    ostr<<info.qq_uin_;

    return ostr;

}

struct TEST_PET_ID

{

    TEST_PET_ID():

        test_uin_(0),

        pet_type_(0)

    {

    }

    ~TEST_PET_ID()

    {

    }

    unsigned int      test_uin_;

    unsigned short    pet_type_;

};

std::ostringstream & operator<< (std::ostringstream &ostr,const TEST_PET_ID &info)

{

    ostr<< info.test_uin_; //出错的代码,错误C2666

    ostr<< info.pet_type_;

    return ostr;

}

//测试
int main(int /*argc*/ ,char * /*argv*/ [])

{

    return 0;

}

TEST_QQ_UIN 有一个单参数的构造函数,而且前面没有加explicit,所以编译器在处理unsigned int作为参数的时候,可以转换为TEST_QQ_UIN,编译器也无法知道是使用哪个ostringstream输出函数,这样导致了编译器报告错误。BTW:其他兄弟利用” ”避免错误,应该是MSVC++的一个bug。
所以单参的构造函数,没有特别情况下,在构造函数前面都加入explicit,避免这种默认的转换。这个Effective C++讲过了,这儿有炒剩饭的嫌疑。糟糕的是,很多事情只有经历了,才知道痛苦。

posted on 2011-02-24 13:12  天天编程  阅读(332)  评论(0编辑  收藏  举报