GCC对char指针的处理和其他C++编译器处理不一样

hqylfy 2008-09-16 03:34:29
以下是代码
头文件:char_test.h
#ifndef CHAR_TESTH
#define CHAR_TESTH

#include <string.h>
#include <stdio.h>

class Test
{
public:
Test(char *p);
~Test();
operator char*() const;

private:
char *m_pBuf;
int m_nBufLen;
};

inline bool operator==(const Test& s1, const Test& s2)
{
return (strcmp(s1 , s2)==0);
}

inline bool operator==(const Test& s1, char * s2)
{
return (strcmp(s1 , s2) == 0) ;
}
#endif
CPP文件:char_test.cpp

#include "char_test.h"

Test::Test(char *p)
{
long nLen = strlen(p);
if (nLen == 0)
{
return;
}

m_pBuf = new char[nLen + 1];
strcpy(m_pBuf , p);
m_nBufLen = nLen + 1;
}
Test::~Test()
{
if (m_pBuf)
{
delete []m_pBuf;
}
}
Test::operator char*() const
{
return m_pBuf;
}
main文件:
#include <cstdlib>
#include <iostream>
#include "char_test.h"

using namespace std;

int main(int argc, char *argv[])
{
Test Test1("test");
if (Test1 == "test")
{
printf("==\r\n");
}else
{
printf("!=\r\n");
}
system("PAUSE");
return EXIT_SUCCESS;
}
这段程序在BCB6.0、VC6.0、AIX的xlC均编译通过,但是用GCC编译提示:
ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
bool operator==(const Test&, char*)
operator==(const char*, const char*) <built-in>
提示"=="操作符存在二义性,不知道是不是GCC对于这类对二义性审查要求更严格?
...全文
214 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
llrock 2008-09-17
  • 打赏
  • 举报
回复
实在不好意思,好像必须要提供2个。
仔细想了一下是因为提供了operator const char*() const ,这个,所以由于自动转换将Test s隐式转换为了const char*,所以和系统的 ==(const char*,const char*)发生了二义性
llrock 2008-09-17
  • 打赏
  • 举报
回复
class Test
{
public:
Test(const char *p)
{
long nLen = (long)strlen(p);
if (nLen == 0)
{
return;
}

m_pBuf = new char[nLen + 1];
strcpy(m_pBuf , p);
m_nBufLen = nLen + 1;
}

~Test()
{
if (m_pBuf)
{
delete []m_pBuf;
}
}
operator const char*() const
{
return m_pBuf;
}
private:
char *m_pBuf;
int m_nBufLen;
public:

bool operator==(const Test &s) const
{
return strcmp(this->m_pBuf,s.m_pBuf)==0;
}

bool operator==(const char *s) const
{
return strcmp(m_pBuf,s)==0;
}
};
hqylfy 2008-09-17
  • 打赏
  • 举报
回复
不过测试的结果显示,即使我把operator==(const Test& s1, const Test& s2)屏蔽掉
编译的时候还是报一样的错误

[Quote=引用 16 楼 llrock 的回复:]
GCC和VC8 目前采用C99标准。

VC7及以前版本只兼容绝大部分了c90标准。

12楼 正解,保留两种中的任何一种就可以了,因为你重载了*
[/Quote]
llrock 2008-09-17
  • 打赏
  • 举报
回复
GCC和VC8 目前采用C99标准。

VC7及以前版本只兼容绝大部分了c90标准。

12楼 正解,保留两种中的任何一种就可以了,因为你重载了*
hqylfy 2008-09-16
  • 打赏
  • 举报
回复
确实如此,只好改为
printf("%s" , (char *)Test1)或者printf(Test1);

[Quote=引用 11 楼 Joey_cc 的回复:]
引用 10 楼 hqylfy 的回复:
printf("%s" , Test1);
用GCC编译后执行,CORE掉了
但是在BCB和VC、AIX的xlC都执行得很好


Test是non-POD类型。GCC不支持non-POD类型的变参传参。一般GCC会提示:
warning: cannot pass objects of non-POD type 'class Test' through '...'; call will abort at runtime
[/Quote]
hqylfy 2008-09-16
  • 打赏
  • 举报
回复
嗯,报错的是
inline bool operator==(const Test& s1, char * s2)
{
return (strcmp(s1 , s2) == 0) ;
}
不过修改为
inline bool operator==(const Test& s1,const char * s2)
{
return (strcmp(s1 , s2) == 0) ;
}
就可以编译通过,我觉得GCC在词法分析后,const Test& s1理解为const char *s1
这时就变成
inline bool operator==(const char *s1,const char * s2)
{
return (strcmp(s1 , s2) == 0) ;
}
如此似乎比较符合其提示中的operator==(const char*, const char*)内建操作符
但是就比较疑惑,是不是标准的C++中就只能做一次转换?
还是这样去理解本身存在误解
hooked 2008-09-16
  • 打赏
  • 举报
回复
这是一个精确匹配的问题。其实它报的错已经比较明朗了:
Test1 == "test";
一种是把"test"从const char* 转成char*,来匹配inline bool operator==(const Test& s1, char * s2);
另一种是把Test1转成const char*,来匹配内建的操作符operator==(const char*, const char*)。
按C++标准,其实这里存在一些问题:
1. const char* 是不应该可以转为char* 的,所以它是不应该去匹配第一种情况的。
2. C++标准里有operator==(const char*, const char*)这一内建的操作符么?我不记得有。但如果确实有,那也不应该匹配这个,因为类里定义的是 operator char*() const;而不是operator const char*() const;这就是说需要先把Test1从Test转到char*,再从char* 转到const char*,但这种隐式的二次转换在C++里是不支持的(只支持一次转换,至于为什么不支持这种隐式的二次转换,原来看过一下,现在忘了)。
综上,结论就是.....大家自己下吧(其实GCC也不是那么标准,GCC的粉丝千万别拍我)

BTW,12楼的朋友估计看得不仔细,这里编译器给的二义性报错其实和inline bool operator==(const Test& s1, const Test& s2) 没什么关系,编译器不会去找它的。
帅得不敢出门 2008-09-16
  • 打赏
  • 举报
回复
Test1 == "test"
有个隐匿转换后,这个产生二义性了.

inline bool operator==(const Test& s1, const Test& s2)
{
return (strcmp(s1 , s2)==0);
}

inline bool operator==(const Test& s1, char * s2)
{
return (strcmp(s1 , s2) == 0) ;
}
Joey_cc 2008-09-16
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 hqylfy 的回复:]
printf("%s" , Test1);
用GCC编译后执行,CORE掉了
但是在BCB和VC、AIX的xlC都执行得很好

[/Quote]
Test是non-POD类型。GCC不支持non-POD类型的变参传参。一般GCC会提示:
warning: cannot pass objects of non-POD type 'class Test' through '...'; call will abort at runtime
hqylfy 2008-09-16
  • 打赏
  • 举报
回复
printf("%s" , Test1);
用GCC编译后执行,CORE掉了
但是在BCB和VC、AIX的xlC都执行得很好
K行天下 2008-09-16
  • 打赏
  • 举报
回复
GCC对标准的支持很好
hqylfy 2008-09-16
  • 打赏
  • 举报
回复
把inline bool operator==(const Test& s1, char * s2) 修改为
inline bool operator==(const Test& s1,const char * s2)

已经OK
我觉得是GCC对于标准执行比其他C++编译器更彻底导致
不知道是否如此
hqylfy 2008-09-16
  • 打赏
  • 举报
回复
改了,还是不行,一样的提示

[Quote=引用 6 楼 xkyx_cn 的回复:]
得改一下:
return (strcmp(s1.m_pBuf, s2)==0);

引用 4 楼 lann64 的回复:

不提供operator char*() const
这一句也不行
return (strcmp(s1 , s2)==0);
[/Quote]
xkyx_cn 2008-09-16
  • 打赏
  • 举报
回复
得改一下:
return (strcmp(s1.m_pBuf, s2)==0);

[Quote=引用 4 楼 lann64 的回复:]

不提供operator char*() const
这一句也不行
return (strcmp(s1 , s2)==0);
[/Quote]
luxiaoxun 2008-09-16
  • 打赏
  • 举报
回复
没有 拷贝构造函数 和 operator = 和这个有关系吗?
lann64 2008-09-16
  • 打赏
  • 举报
回复

不提供operator char*() const
这一句也不行
return (strcmp(s1 , s2)==0);
hqylfy 2008-09-16
  • 打赏
  • 举报
回复
不提供operator char*() const
(Test1 == "test")这句编译就报错了
本来是想偷懒一些,重载operator char*() const在处理代码的时候可以省很多事
比如可以直接printf("%s",Test)
xkyx_cn 2008-09-16
  • 打赏
  • 举报
回复
如果你不提供operator char*() const;呢?
lann64 2008-09-16
  • 打赏
  • 举报
回复
跟bcb6,vc6比,gcc更符合标准一点

64,634

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧