所以我试图将枚举连接到std :: string。为此我写了下面的代码。
typedef enum { NODATATYPE = -1,
DATATYPEINT,
DATATYPEVARCHAR
} DATATYPE;
inline std::string operator+(std::string str, const DATATYPE dt){
static std::map<DATATYPE, std::string> map;
if (map.size() == 0){
#define INSERT_ELEMENT(e) map[e] = #e
INSERT_ELEMENT(NODATATYPE);
INSERT_ELEMENT(DATATYPEINT);
INSERT_ELEMENT(DATATYPEVARCHAR);
#undef INSERT_ELEMENT
}
return str + map[dt];
}
和
DATATYPE dt1 = DATATYPEINT;
std::string msg = "illegal type for operation" + dt1;
我收到以下警告,编译此代码。
警告:ISO C ++说这些是不明确的,即使第一个的最差转换比第二个的最差转换更好:std :: string msg =“非法操作类型”+ dt1; absyn.cpp:642:55:注意:候选1:运算符+(const char *,long int) 在file.cpp中包含的文件中:4:0:file.h:18:20:注意:候选2:std :: string运算符+(std :: string,DATATYPE)内联std :: string运算符+(std :: string str ,const DATATYPE dt){
这个警告究竟意味着什么,以及如何解决它?
答案 0 :(得分:2)
传递给运算符的是const char*
(对于字符串文字)和DATATYPE
。由于没有重载operator+(const char*, DATATYPE)
,编译器会查找可以隐式转换参数的重载。候选人在警告中:
operator+(const char*, long int)
operator+(std::string, DATATYPE)
第一个参数可以从const char*
转换为std::string
,或者第二个参数可以从DATATYPE
转换为long int
。所以第一次超载&#34;胜利&#34;基于第一个参数和第二个过载的重载决策&#34;胜利&#34;在第二个论点的基础上。因为没有超载,所以&#34;胜利&#34;根据这两个论点提出的决议,它们含糊不清。
编译器警告您,因为它怀疑它可能选择了与您打算调用的不同的重载。如果您使用gcc上的-pedantic
进行编译,则会获得error: ambiguous overload for
...而不仅仅是警告。
解决方案是通过传递完全匹配的类型的参数来消除调用的歧义。一个简单的方法是:
std::string msg = std::string("illegal type for operation") + dt1;
或更好的c ++ 14
std::string msg = "illegal type for operation"s + dt1;