https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102257
Andrew Pinski <pinskia at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- See Also| |https://gcc.gnu.org/bugzill | |a/show_bug.cgi?id=102247 --- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Take: #include <tuple> #include <string> int main() { std::tuple<std::string, int, int> t{{}, 0}; } ----- CUT ---- GCC does reject this though with the following error message: <source>: In function 'int main()': <source>:6:44: error: converting to 'std::allocator_arg_t' from initializer list would use explicit constructor 'constexpr std::allocator_arg_t::allocator_arg_t()' 6 | std::tuple<std::string, int, int> t{{}, 0}; | ^ So the question becomese does the conversion happen while chosing the overload for the tuple constructor? Looks like GCC is the only one which rejects this as being ambiguous too. I did try: struct tag{}; struct alloc {explicit alloc(int){};}; template<typename T1, typename T2> struct tuple { tuple(tag, const alloc&); tuple(const T1&, const T2&); }; class t2{}; tuple<t2,int> tt{{},0}; and GCC accepts this so is suprising based on the error message of the other one. Also you don't need std::string, a simple class like this will fail: #include <tuple> class t2{}; int main() { std::tuple<t2, int> t{{}, 0}; }