简体   繁体   中英

Appending (uint8_t)0x00 to a std::string causes ambiguous overload error on cygwin?

Am I going crazy, or is this a bug with the cygwin g++ compiler?

This works:

std::string record;
record += (uint8_t)1;

It also is totally cool with appending a const variable with value 0:

const uint8_t tZero = 0x00;
std::string record;
record += tZero;

However, running this code causes an ambiguous operator overload error:

std::string record;    
record += (uint8_t)0;

The candidates it provides make no sense given the explicit cast, especially since one of the candidates seems to be identical to what is given in the error:

sources/logger.cpp:55:20: error: ambiguous overload for `operator+=' (operand types are `std::string {aka std::basic_string<char>}' and `uint8_t {aka unsigned char}')
    record += (const uint8_t)0;

note: candidates:
    operator+=(const basic_string& __str)
    operator+=(const _CharT* __s)
    operator+=(_CharT __c)

This error also does NOT appear in visual studio, it compiles and appends a 0x00 byte just as I expect.

For reference, I'm using strings as buffers for binary log data. There's probably a better container to use, but being able to += bytes in is too useful to not have.

Does cygwin have a bug with its string implementation, or is this supposed to cause an error since it's 0? I don't mind using a const variable to fix the error, but it will look weird since this process is repeated multiple times through the code with other values.

This is a fairly recent change to the C++ language. Nowadays, your code should call operator+=(_CharT) . In the past, your code should fail due to an ambiguity even with const uint8_t tZero = 0x00; . You're dealing with a compiler that's partially implemented that change.

Before that change to the language, any integer constant expression with a value of zero was implicitly convertible to any pointer type and yielded a null pointer. That's why (uint8_t)0 could be converted to char , or to const char * .

Now, only a literal 0 can be converted to pointer types. tZero , or even (uint8_t)0 , should no longer convert to const char * . This resolves the ambiguity: only the conversion to char still remains as a possibility.

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