首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

C++对重装的参数匹配规则疑问解决思路

2012-02-21 
C++对重装的参数匹配规则疑问 代码如下://file:tt.cpp#includestring#includeiostreamusingnamespaces

C++对重装的参数匹配规则疑问

代码如下:
//   file   :   tt.cpp
#include   <string>
#include   <iostream>

using   namespace   std;

typedef   unsigned   char     u8;
typedef   unsigned   int       u32;

//   这个类重装了到std::string,   unsigned   char,   unsigned   int三个类型的类型转换方法(代码的返回值只是演示)
class   CC
{
public:
operator   string()   const
{
return   "string ";
}
operator   u8()   const
{
return   8;
}
operator   u32()   const
{
return   32;
}
};

//   这个类的“=”符号重装了接受三个不同的类型
class   TT
{
public:
TT&   operator   =   (const   string&   str)  
{
cout   < <   "using   string "   < <   endl;
return   *this;  
}
TT&   operator   =   (signed   char   cc)
{
cout   < <   "using   char "   < <   endl;
return   *this;
}
TT&   operator   =   (const   char*   ptr)
{
cout   < <   "using   pointer "   < <   endl;
return   *this;
}  
};
//   编译命令:g++   tt.cpp   -o   tt
int   main(int   argc,   char*   argv[])
{
                TT   tt;
                CC   cc;
                //   下面这个的原意是希望cc转换成std::string,然后通过“=”操作符号赋值给tt的。
                tt   =   cc;
                //   但是,在GCC3.4上编译总是报告“混淆”,错误如下
//tt.cpp:   In   function   `int   main(int,   char**) ':
//tt.cpp:49:   error:   ambiguous   overload   for   'operator= '   in   'ttt   =   cc '
//tt.cpp:29:   note:   candidates   are:   TT&   TT::operator=(const   std::string&)
//tt.cpp:34:   note:                                   TT&   TT::operator=(signed   char)
//tt.cpp:39:   note:                                   TT&   TT::operator=(const   char*)   <near   match>

                //   在VC2005和GCC3.2上都能正确的匹配,符合原意。
                //   我的怀疑是不是GCC3.4的类型匹配规则有BUG?按照最匹配原则,应该匹配std::string,而u8要是想匹配到TT&   operator   =   (signed   char   cc)必须有一个精度损失的类型转换才能完成,显然不应该是一个合适的参数匹配,因此,不应该存在参数匹配混淆才对。

                return   0;
}
                //   请教各位大侠,是不是有什么GCC的参数没设置正确导致?又或者是我的理解不对?还是GCC的BUG?望高手指点。
                //   BTW:不要告诉我用tt   =   (string)   cc;这样的方式,这个方式肯定是可以找到正确的参数匹配的,但是现有代码很多,改起来工作量很大,而且也不优雅:)



[解决办法]
太多的自定义类型转换符的出现,一般都是一个错误。


建议你改掉这个风格。
[解决办法]
通信实体之间已经约定好了0x1001就是传递字符串,0x1002就是传递u8整数
------------------------------
这种情况在很多地方出现,最典型的就是数据库访问。这里的核心问题是动态的类型转换。使用类型操作符是最危险的方案。可靠和准确永远是首要的,只有在前者的基础上才能谈论优雅。所以,std::string val1 = getTLV(0x1001).getString(); 是更好的选择。就像std::string那样。凡是涉及到类型转换,显式的永远比隐式的更加安全可靠。
当然也有一些优化方案可供选择。一种方案是使用函数模板,及其特化:
template <int tag>
void getTLV();

template <>
string getTLV <0x1001> (){...}
template <>
u8 getTLV <0x1002> (){...}
...

如此,使用时,通过实参实例化模板,获得正确的函数签名:
std::string val1 = getTLV <0x1001> ();
u8 val2 = getTLV <0x1002> ();
std::string val1 = getTLV <0x1002> (); //编译错误,返回类型不匹配
u8 val2 = getTLV <0x1001> (); //同上
这样,无需采用类型转换操作符,即可解决类型匹配问题。而不同类型间的转换,如u8=> string等可以通过重载operator=或者专用的转换函数实现。重载operator=的副作用大大小于类型转换操作符。

热点排行