https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82716
Bug ID: 82716 Summary: struct/class vs. tuple_element/tuple_size Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: marc.mutz at kdab dot com Target Milestone: --- I'm trying to support the tuple protocol for Qt's QPair: namespace std { // these have to be 'class', because MSVC warns about struct/class mismatch, and // in the std, they are classes: template <typename T1, typename T2> class tuple_size<QT_PREPEND_NAMESPACE(QPair)<T1,T2>> : public std::integral_constant<size_t, 2> {}; template <typename T1, typename T2> class tuple_element<0, QT_PREPEND_NAMESPACE(QPair)<T1, T2>> { public: using type = T1; }; template <typename T1, typename T2> class tuple_element<1, QT_PREPEND_NAMESPACE(QPair)<T1, T2>> { public: using type = T2; }; } I get these warnings from clang: 68 : <source>:68:5: error: 'tuple_size' defined as a class template here but previously declared as a struct template [-Werror,-Wmismatched-tags] class tuple_size<~~~> : public std::integral_constant<std::size_t, 2> {}; ^ /opt/compiler-explorer/gcc-7.1.0/lib/gcc/x86_64-linux-gnu/7.1.0/../../../../include/c++/7.1.0/utility:88:5: note: did you mean class here? struct tuple_size; ^ 71 : <source>:71:5: error: 'tuple_element' defined as a class template here but previously declared as a struct template [-Werror,-Wmismatched-tags] class tuple_element<I, ~~~~> ^ /opt/compiler-explorer/gcc-7.1.0/lib/gcc/x86_64-linux-gnu/7.1.0/../../../../include/c++/7.1.0/utility:112:5: note: did you mean class here? struct tuple_element; ^ 2 errors generated. Compiler exited with result code 1 Here's a stripped-down example: https://godbolt.org/g/sUZxAQ Works with -stdlib=libc++: https://godbolt.org/g/bW4u1u The standard says that tuple_element and tuple_size are struct and continues to use it as class (http://eel.is/c++draft/tuple.helper), and so does libstdc++, which means that there's no way to write a tuple_size specialisation that will avoid the warning. Expected: libstdc++ recognizes that it may be used with compilers that warn about struct/class mismatch, picks one of the two, and sticks to it, so one can at least use #ifdefs to pick which one to use.