The following code compiles fine with msvc and clang but issues a narrowing warning for gcc 12.1. I think gcc is trying to do the wrong thing: It tries to convert const char* to bool even though there exists a std::string constructor in the ref object which would arguably be more fitting. Not only that but you can try to "explicit out" the bool constructor in which case it tries to convert to int for the int constructor. If you explicit out the int constructor as well it fails completely (it doesn't even seem to look at the string constructor). Seems like a gcc bug to me as it is working fine with all other compilers.
#include <variant>
#include <string>
struct ref
{
ref(int);
ref(bool);
ref(std::string);
ref(std::initializer_list<ref>);
std::variant<std::monostate, int, bool, std::string, std::initializer_list<ref>> value_;
};
struct container : public ref
{
using ref::ref;
};
ref::ref(int init) : value_{init} {}
ref::ref(bool init) : value_{init} {}
ref::ref(std::string init) : value_{init} {}
ref::ref(std::initializer_list<ref> init) : value_{init} {}
int main()
{
container some_container = { 1, true, 1, { {"itemA", 2}, {"itemB", true}}};
}
gcc warning:
<source>: In function 'int main()':
<source>:30:49: warning: narrowing conversion of '(const char*)"itemA"' from 'const char*' to 'bool' [-Wnarrowing]
30 | container some_container = { 1, true, 1, { {"itemA", 2}, {"itemB", true}}};
| ^~~~~~~
<source>:30:63: warning: narrowing conversion of '(const char*)"itemB"' from 'const char*' to 'bool' [-Wnarrowing]
30 | container some_container = { 1, true, 1, { {"itemA", 2}, {"itemB", true}}};
|
I just tried expliciting out the int and bool constructor with msvc and clang which fail as well. Leaves me wondering what is happening behind the curtains.