T1, T2, T3>> { using type = T2; };
    template<typename T1, typename T2, typename T3>
        struct std::tuple_element<2, Triple<T1, T2, T3>> { using type = T3; };
     
     
    template<typename... Args> struct TripleTypes
    {
        static_assert(3 == sizeof...(Args), "Expected exactly 3 type names");
        template<[std::size_t](http://en.cppreference.com/w/cpp/types/size_t) N>
        using type = typename std::tuple_element_t<N, Triple<Args...>>;
    };
     
    int main()
    {
        TripleTypes<char, int, float>::type<1> i{42};
        [std::cout](http://en.cppreference.com/w/cpp/io/cout) << i << '\n';
     
        using Tri = Triple<int, char, short>; //< Program-defined type
        static_assert([std::is_same_v](http://en.cppreference.com/w/cpp/types/is_same)<std::tuple_element_t<0, Tri>, int> &&
                      [std::is_same_v](http://en.cppreference.com/w/cpp/types/is_same)<std::tuple_element_t<1, Tri>, char> &&
                      [std::is_same_v](http://en.cppreference.com/w/cpp/types/is_same)<std::tuple_element_t<2, Tri>, short>);
     
        using Tuple = [std::tuple](http://en.cppreference.com/w/cpp/utility/tuple)<int, char, short>;
        static_assert([std::is_same_v](http://en.cppreference.com/w/cpp/types/is_same)<std::tuple_element_t<0, Tuple>, int> &&
                      [std::is_same_v](http://en.cppreference.com/w/cpp/types/is_same)<std::tuple_element_t<1, Tuple>, char> &&
                      [std::is_same_v](http://en.cppreference.com/w/cpp/types/is_same)<std::tuple_element_t<2, Tuple>, short>);
     
        using Array3 = [std::array](http://en.cppreference.com/w/cpp/container/array)<int, 3>;
        static_assert([std::is_same_v](http://en.cppreference.com/w/cpp/types/is_same)<std::tuple_element_t<0, Array3>, int> &&
                      [std::is_same_v](http://en.cppreference.com/w/cpp/types/is_same)<std::tuple_element_t<1, Array3>, int> &&
                      [std::is_same_v](http://en.cppreference.com/w/cpp/types/is_same)<std::tuple_element_t<2, Array3>, int>);
     
        using Pair = [std::pair](http://en.cppreference.com/w/cpp/utility/pair)<Tuple, Tri>;
        static_assert([std::is_same_v](http://en.cppreference.com/w/cpp/types/is_same)<std::tuple_element_t<0, Pair>, Tuple> &&
                      [std::is_same_v](http://en.cppreference.com/w/cpp/types/is_same)<std::tuple_element_t<1, Pair>, Tri>);
     
        using Sub = std::[ranges::subrange](http://en.cppreference.com/w/cpp/ranges/subrange)<int*, int*>;
        static_assert([std::is_same_v](http://en.cppreference.com/w/cpp/types/is_same)<std::tuple_element_t<0, Sub>, int*> &&
                      [std::is_same_v](http://en.cppreference.com/w/cpp/types/is_same)<std::tuple_element_t<1, Sub>, int*>);
    }

Output:

    
    
    42

###  [ [ edit
](/mwiki/index.php?title=cpp/utility/tuple_element&action=edit&section=6 "Edit
section: Defect reports") ]  Defect reports

The following behavior-changing defect reports were applied retroactively to
previously published C++ standards.

DR  |  Applied to  |  Behavior as published  |  Correct behavior   
---|---|---|---  
[ LWG 2212 ](https://cplusplus.github.io/LWG/issue2212) |  C++11  |  specializations for cv types were not required in some headers, which led to ambiguity  |  required   
  
###  [ [ edit
](/mwiki/index.php?title=cpp/utility/tuple_element&action=edit&section=7 "Edit
section: See also") ]  See also

[ Structured binding ](/w/cpp/language/structured_binding "cpp/language/structured binding") (C++17)  |  binds the specified names to sub-objects or tuple elements of the initializer  [ [edit] ](https://en.cppreference.com/mwiki/index.php?title=Template:cpp/language/dsc_structured_binding&action=edit)  
---|---  
[ tuple_size  ](/w/cpp/utility/tuple_size "cpp/utility/tuple size") (C++11)  |  obtains the number of elements of a tuple-like type   
(class template)  [ [edit]
](https://en.cppreference.com/mwiki/index.php?title=Template:cpp/utility/dsc