简体   繁体   中英

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

So I'm trying to concatenate an enum to an std::string. For this I wrote the following code.

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];
}

and

DATATYPE dt1 = DATATYPEINT;
std::string msg = "illegal type for operation" + dt1;

I'm getting the following warning compiling this code.

warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: std::string msg = "illegal type for operation" + dt1; absyn.cpp:642:55: note: candidate 1: operator+(const char*, long int) In file included from file.cpp:4:0: file.h:18:20: note: candidate 2: std::string operator+(std::string, DATATYPE) inline std::string operator+(std::string str, const DATATYPE dt){

What does this warning exactly mean, and how to solve it?

What you pass to the operator is a const char* (to a string literal) and a DATATYPE . Since there is no overload operator+(const char*, DATATYPE) , the compiler looks for overloads where the parameters can be implicitly converted. The candidates are in the warning:

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

The first parameter can be converted from const char* to std::string or the second parameter can be converted from DATATYPE to long int . So the first overload "wins" the overload resolution on the basis of first parameter and the second overload "wins" on the basis of the second argument. Since there is no overload that "wins" the resolution on the basis of both arguments, they are ambiguous.

The compiler warns you because it suspects that it may have chosen different overload than what you meant to call. If you compile with -pedantic on gcc you'll get error: ambiguous overload for ... instead of just a warning.

The solution is to disambiguate the call by passing parameters of types that match exactly. A simple way would be:

std::string msg = std::string("illegal type for operation") + dt1;

or nicer in c++14

std::string msg = "illegal type for operation"s + dt1;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM