I want to be able to initialize container with a brace init list and not have to specify types. This is more difficult as I have nested initializers. Now I'm at the point where it almost works, but there are two overloads for initializer_list in the variant wrapper and the compiler can't figure out which to use.
Actually in this case the call is not even ambiguous as only class keyval takes a string as its first argument, which means the keyval overload of the variant wrapper should be chosen. But how can I tell this to the compiler?
My code (CompilerExplorer):
#include <string>
#include <variant>
template <typename... T> struct vwrapper;
using val = vwrapper<std::monostate, struct array, struct obj, int, bool>;
template <typename... T>
struct vwrapper : public std::variant<T...>
{
vwrapper(int);
vwrapper(bool);
vwrapper(std::initializer_list<struct keyval>);
vwrapper(std::initializer_list<val>);
// vwrapper(obj);
// vwrapper(array);
vwrapper(std::monostate);
};
struct obj
{
obj() = default;
obj(std::initializer_list<struct keyval> init) {
}
};
struct array
{
array() = default;
array(std::initializer_list<val> init) {
}
};
struct keyval
{
keyval() = default;
keyval(std::string, val);
};
template <typename... T>
vwrapper<T...>::vwrapper(int) {}
template <typename... T>
vwrapper<T...>::vwrapper(bool) {}
template <typename... T>
vwrapper<T...>::vwrapper(std::initializer_list<val>) {}
template <typename... T>
vwrapper<T...>::vwrapper(std::initializer_list<struct keyval>) {}
// template <typename... T>
// vwrapper<T...>::vwrapper(obj) {}
// template <typename... T>
// vwrapper<T...>::vwrapper(array) {}
keyval::keyval(std::string str, val value) { }
struct container : public array, public obj
{
using array::array;
using obj::obj;
};
int main()
{
container some_container = { 1, 2, true, false, 2, { { "hello", 2 }, { "mogli", true }}};
}
A minimal version of your snippet is
At which point the ambiguity presents itself: a string literal is convertible to a
bool. Bothval{"", 2}andkeyval{"", 2}are valid expressions, with the first being interpreted asTo avoid the ambiguity, force the type to be
keyval