Compiles with clang, doesn't under gcc 8.1.0: template <typename, typename> struct is_same { static constexpr bool value = false; }; template <typename T> struct is_same<T, T> { static constexpr bool value = true; }; int main() { const int Array[] = {1}; auto[One] = Array; static_assert(is_same<decltype(One), const int>::value); // fail } [dcl.struct.bind]p1 is pretty clear here that the type of the underlying structured binding element is const int[1], and so per [dcl.struct.bind]p2 the element type is const int and thus so is also One's type.
Jason/Jonathan, is that true? What exactly shall be the qualification in the array case? Ored type quals of the initializer's element type and provided quals from the structured binding declaration? If so, it would be something like: --- gcc/cp/pt.c.jj 2018-06-04 15:47:24.633937198 +0200 +++ gcc/cp/pt.c 2018-06-05 09:12:56.151035636 +0200 @@ -26734,10 +26734,15 @@ do_auto_deduction (tree type, tree init, && auto_node == type && init != error_mark_node && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE) - /* [dcl.decomp]/1 - if decomposition declaration has no ref-qualifiers - and initializer has array type, deduce cv-qualified array type. */ - return cp_build_qualified_type_real (TREE_TYPE (init), TYPE_QUALS (type), - complain); + { + /* [dcl.decomp]/1 - if decomposition declaration has no ref-qualifiers + and initializer has array type, deduce cv-qualified array type. */ + int type_quals = TYPE_QUALS (type); + tree eltype = strip_array_types (TREE_TYPE (init)); + type_quals |= TYPE_QUALS (eltype); + return cp_build_qualified_type_real (TREE_TYPE (init), type_quals, + complain); + } else if (AUTO_IS_DECLTYPE (auto_node)) { bool id = (DECL_P (init)
I think this is a bug in the standard. The cv-qualifiers of the array type should be discarded, as they would be for any normal auto deduction.
I disagree and think that Clang is wrong. The top-level qualifiers of T (the type of One) should be "cv", and cv is "the cv-qualifiers in the decl-specifier-seq". The decl-specifier-seq is "auto", not "const auto". That "auto" will infer "const int" doesn't seem to be relevant. Discussion on https://stackoverflow.com/q/53726135/560648.
Richard, do you know if there's an issue for this yet?
This was just reported as http://lists.isocpp.org/core/2018/12/5320.php; I don't believe it's on the core issues list yet. [@Tomalak, I think the standard is clear here: "If the assignment-expression in the initializer has array type A and no ref-qualifier is present, e has type cv A" Here, A is the array type 'const int[1]' and cv is empty, so e has type 'const int[1]'. But, as noted in comment#2, that seems like the wrong outcome. It also contradicts the non-normative note in [dcl.struct.bind]p3, which further suggests that this outcome was probably not the intent of the wording.]
Seems to be fixed in GCC 11+.
We accept it since r11-7997-g66de517b1c1dd22df7914f8e9a083cd5a73adbe2 , not sure if on purpose or by accident. Has there been a core issue created for the above? If so, has it been resolved?
(In reply to Jakub Jelinek from comment #7) > Has there been a core issue created for the above? None that I can find.