std::string派生类实现operator const char const出错的问题,请帮我看看

来源:互联网  时间:2016/8/31 13:17:18

关于网友提出的“ std::string派生类实现operator const char const出错的问题,请帮我看看”问题疑问,本网通过在网上对“ std::string派生类实现operator const char const出错的问题,请帮我看看”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:

问题: std::string派生类实现operator const char const出错的问题,请帮我看看
描述:


// 先包含头文件
#include 
using namespace std;


class CCrossString : public string
{
public:
CCrossString(const char* lpsz) : string(lpsz) {};
char operator []( size_t nIndex ) const
{
return __super::operator[](nIndex);
}
operator const char*() const // 实现自动类型转换
{
return (const char*)__super::data();
}
};


        //开始使用
CCrossString str("abc");
const char* lpsz = (const char*)str;// lpsz 的内容现在就是 "abc"
char c = str[1];//如果把此句注释掉就没有问题

如上,如果使用char c = str[1];这样的语句编译时就报错:
1>正在编译...
1>CrossString.cpp
1>f:\程序设计\vs2008\crossstring\crossstring\crossstring.cpp(60) : error C2666: “CCrossString::operator []”: 2 个重载有相似的转换
1>        f:\程序设计\vs2008\crossstring\crossstring\crossstring.cpp(42): 可能是“char CCrossString::operator [](size_t) const”
1>        或       “内置 C++ operator[(const char *, int)”
1>        试图匹配参数列表“(CCrossString, int)”时
解决方案1:

引用 11 楼 zhllxt 的回复:
顶一下,有没有大神帮忙解释一下为什么用了 
template 
char operator []( T nIndex ) const
模板函数就解决了呢?

有没有看我在6楼的解决方法?为什么要强调显示调用?
因为这里有一个自动转换的问题,str[]可以认为是CCrossString[],也可以认为是const char*(str)[]。
这才造成了二义性。强制转换很好用,但是尽可能不要隐式的自动转换,因为很容易造成你的这种问题。记得加explicit关键字。 解决方案2:

引用 10 楼 zhllxt 的回复:
Quote: 引用 9 楼 ri_aje 的回复:

把 operator [] 改成这样。

template 
char operator []( T nIndex ) const

这不是编译器 bug,原来的写法 str[1] 会导致二义性,因为 [] 和 const char* 都适用,而且都存在隐式类型转换,无法决议。

太好了,你提供的方法解决了。
能否帮我解释一下具体原因“原来的写法 str[1] 会导致二义性,因为 [] 和 const char* 都适用”我实在找不出来在哪儿或哪些代码能让我明白这个问题。
另外6楼的方法也可以实现,但是就是不够优雅,对于用户来说代码直观性差了。

主楼的写法,编译器遇到 str[1] 后发现
(1) 可以把 str 转换成一个 char const*,然后当指针用,因为使用的是你提供的 operator char const*,所以这种调用方法使用用户自定义转换。
(2) 可以调用 operator [] 完成操作,但是实参 1 的类型是 int,而形参的类型是 size_t,所以需要 int 到 size_t 的转换,这种调用方法使用隐式类型转换。
标准规定 (2) 比 (1) 的优先级高,所以重载解析应该选择 (2),程序编译执行应该都没有问题。
但 VS 家的编译器却出编译错误,所以这是编译器的 bug,我在 #9 关于这点说错了。
bug 就 bug 吧,VS 总是不太给力的。
#9 给的方法是一个临时的补救方案。
变成 template T 以后,编译器根据 str[1] 中的实参类型推导形参类型,因此 1 推出 int。
重要的是无论实参是什么类型,推导出的形参都必然具有相同的类型,所以 (2) 的调用中就不存在隐式类型转换的问题了,因此 (2) 变成完全匹配。然后看样子 VS 还是能算出来完全匹配比用户自定义转换优先级高,所以就不在抱怨了。就这样。

上一篇给大家推荐一本很不错的C++教材,有很多有趣习题
下一篇孤独的c++ 学习者!!!!!
明星图片
相关文章
《 std::string派生类实现operator const char const出错的问题,请帮我看看》由码蚁之家搜集整理于网络,
联系邮箱:mxgf168#qq.com(#改为@)