C++:将枚举连接到 std::string

C++: concatenate an enum to a std::string

所以我试图将枚举连接到 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 = "illegal type for operation" + dt1; absyn.cpp:642:55: 注意:候选 1:operator+(const char*, long int) 在包含的文件中 file.cpp:4:0: file.h:18:20: 注意:候选 2: std::string operator+(std::string, DATATYPE) inline std::string运算符+(std::string str, const DATATYPE dt){

这个警告到底是什么意思,如何解决?

你传递给运算符的是一个const char*(到一个字符串文字)和一个DATATYPE。由于没有重载operator+(const char*, DATATYPE),编译器会寻找参数可以隐式转换的重载。候选人在警告中:

operator+(const char*, long int)
operator+(std::string, DATATYPE)

第一个参数可以从const char*转换为std::string或者第二个参数可以从DATATYPE转换为long int。所以第一个重载 "wins" 基于第一个参数的重载解析,第二个重载 "wins" 基于第二个参数的重载解析。由于没有重载"wins"基于两个参数的解析,因此它们是模棱两可的。

编译器向您发出警告,因为它怀疑它可能选择了与您打算调用的重载不同的重载。如果您在 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;