Skip to content

<tuple>: Confusing diagnostic for get<T>() when the type doesn't occur exactly once #4575

@StephanTLavavej

Description

@StephanTLavavej

The MSVC STL diagnostic for invalid get<T>() is very confusing (regardless of whether the compiler is MSVC or Clang), whereas libstdc++ and libc++ emit better diagnostics: https://godbolt.org/z/n77dfWr9G

We should verify that both the "not found" and "found more than once" scenarios generate improved diagnostics.

C:\Temp>type meow.cpp
#include <tuple>
using namespace std;
int main() {
    tuple<int, long, double> t{17, 29L, 3.14};
    (void) get<float>(t);
}
C:\Temp>cl /EHsc /nologo /W4 /std:c++latest /MTd /Od /c meow.cpp
meow.cpp
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(928): error C2039: '_Ttype': is not a member of 'std::_Tuple_element<_Ty,std::tuple<>>'
        with
        [
            _Ty=float
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(918): note: see declaration of 'std::_Tuple_element<_Ty,std::tuple<>>'
        with
        [
            _Ty=float
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(928): note: the template instantiation context (the oldest one first) is
meow.cpp(5): note: see reference to function template instantiation '_Ty &std::get<float,int,long,double>(std::tuple<int,long,double> &) noexcept' being compiled
        with
        [
            _Ty=float
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(967): note: see reference to class template instantiation 'std::_Tuple_element<float,std::tuple<int,long,double>>' being compiled
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(928): note: see reference to class template instantiation 'std::_Tuple_element<_Ty,std::tuple<long,double>>' being compiled
        with
        [
            _Ty=float
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(928): note: see reference to class template instantiation 'std::_Tuple_element<_Ty,std::tuple<double>>' being compiled
        with
        [
            _Ty=float
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(928): error C2061: syntax error: identifier '_Ttype'
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(928): error C2039: '_Ttype': is not a member of 'std::_Tuple_element<_Ty,std::tuple<double>>'
        with
        [
            _Ty=float
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(927): note: see declaration of 'std::_Tuple_element<_Ty,std::tuple<double>>'
        with
        [
            _Ty=float
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(928): error C2039: '_Ttype': is not a member of 'std::_Tuple_element<_Ty,std::tuple<long,double>>'
        with
        [
            _Ty=float
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(927): note: see declaration of 'std::_Tuple_element<_Ty,std::tuple<long,double>>'
        with
        [
            _Ty=float
        ]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(967): error C2039: '_Ttype': is not a member of 'std::_Tuple_element<float,std::tuple<int,long,double>>'
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(927): note: see declaration of 'std::_Tuple_element<float,std::tuple<int,long,double>>'
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(967): error C2061: syntax error: identifier '_Ttype'
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(968): error C2061: syntax error: identifier '_Ttype'

C:\Temp>clang-cl /EHsc /nologo /W4 /std:c++latest /MTd /Od /c meow.cpp
In file included from meow.cpp:1:
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(928,67): error: no type
      named '_Ttype' in 'std::_Tuple_element<float, std::tuple<>>'
  928 |     using _Ttype = typename _Tuple_element<_Ty, tuple<_Rest...>>::_Ttype;
      |                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(928,29): note: in
      instantiation of template class 'std::_Tuple_element<float, std::tuple<double>>' requested here
  928 |     using _Ttype = typename _Tuple_element<_Ty, tuple<_Rest...>>::_Ttype;
      |                             ^
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(928,29): note: in
      instantiation of template class 'std::_Tuple_element<float, std::tuple<long, double>>' requested here
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(967,29): note: in
      instantiation of template class 'std::_Tuple_element<float, std::tuple<int, long, double>>' requested here
  967 |     using _Ttype = typename _Tuple_element<_Ty, tuple<_Types...>>::_Ttype;
      |                             ^
meow.cpp(5,12): note: in instantiation of function template specialization 'std::get<float, int, long, double>'
      requested here
    5 |     (void) get<float>(t);
      |            ^
In file included from meow.cpp:1:
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33721\include\tuple(968,12): error: non-const
      lvalue reference to type '_Ttype' (aka 'int') cannot bind to a value of unrelated type 'tuple<int, long, double>'
  968 |     return static_cast<_Ttype&>(_Tuple)._Myfirst._Val;
      |            ^                    ~~~~~~
meow.cpp(5,12): note: in instantiation of function template specialization 'std::get<float, int, long, double>'
      requested here
    5 |     (void) get<float>(t);
      |            ^
2 errors generated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementSomething can be improvedfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions