Type of reference binding from std::tuple [duplicate]












3
















This question already has an answer here:




  • structured bindings: when something looks like a reference and behaves similarly to a reference, but it's not a reference

    2 answers




What is the type of a here?



#include <iostream>
#include <tuple>

using namespace std;

int main()
{
float x{};
std::tuple<int> tpl( x );
auto& [ a ] = tpl;
static_assert( std::is_same_v< decltype( a ), int> );
//static_assert( std::is_same_v< decltype( a ), int&> );
}


According to Standard 11.5/3:




[...] Given the type Ti designated by std::tuple_element<i, E>::type,
variables are introduced with unique names ri of type “reference to
Ti”
initialized with the initializer (11.6.3), where the reference is
an lvalue reference if the initializer is an lvalue
and an rvalue
reference otherwise. Each vi is the name of an lvalue of type Ti that
refers to the object bound to ri; the referenced type is Ti.




Here, i is 0 for the first element (int) and E is std::tuple<int>, so Ti has type std::tuple_element<0, std::tuple<int>>::type, i.e. int. Further ri (a in our case) has type "reference to Ti", i.e. lvalue reference int&, but not just int.
What is wrong in that quote and why int type is deduced by both the compilers clang and gcc?










share|improve this question













marked as duplicate by cpplearner, HolyBlackCat, llllllllll, T.C. c++
Users with the  c++ badge can single-handedly close c++ questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Dec 31 '18 at 12:57


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.























    3
















    This question already has an answer here:




    • structured bindings: when something looks like a reference and behaves similarly to a reference, but it's not a reference

      2 answers




    What is the type of a here?



    #include <iostream>
    #include <tuple>

    using namespace std;

    int main()
    {
    float x{};
    std::tuple<int> tpl( x );
    auto& [ a ] = tpl;
    static_assert( std::is_same_v< decltype( a ), int> );
    //static_assert( std::is_same_v< decltype( a ), int&> );
    }


    According to Standard 11.5/3:




    [...] Given the type Ti designated by std::tuple_element<i, E>::type,
    variables are introduced with unique names ri of type “reference to
    Ti”
    initialized with the initializer (11.6.3), where the reference is
    an lvalue reference if the initializer is an lvalue
    and an rvalue
    reference otherwise. Each vi is the name of an lvalue of type Ti that
    refers to the object bound to ri; the referenced type is Ti.




    Here, i is 0 for the first element (int) and E is std::tuple<int>, so Ti has type std::tuple_element<0, std::tuple<int>>::type, i.e. int. Further ri (a in our case) has type "reference to Ti", i.e. lvalue reference int&, but not just int.
    What is wrong in that quote and why int type is deduced by both the compilers clang and gcc?










    share|improve this question













    marked as duplicate by cpplearner, HolyBlackCat, llllllllll, T.C. c++
    Users with the  c++ badge can single-handedly close c++ questions as duplicates and reopen them as needed.

    StackExchange.ready(function() {
    if (StackExchange.options.isMobile) return;

    $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
    var $hover = $(this).addClass('hover-bound'),
    $msg = $hover.siblings('.dupe-hammer-message');

    $hover.hover(
    function() {
    $hover.showInfoMessage('', {
    messageElement: $msg.clone().show(),
    transient: false,
    position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
    dismissable: false,
    relativeToBody: true
    });
    },
    function() {
    StackExchange.helpers.removeMessages();
    }
    );
    });
    });
    Dec 31 '18 at 12:57


    This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.





















      3












      3








      3









      This question already has an answer here:




      • structured bindings: when something looks like a reference and behaves similarly to a reference, but it's not a reference

        2 answers




      What is the type of a here?



      #include <iostream>
      #include <tuple>

      using namespace std;

      int main()
      {
      float x{};
      std::tuple<int> tpl( x );
      auto& [ a ] = tpl;
      static_assert( std::is_same_v< decltype( a ), int> );
      //static_assert( std::is_same_v< decltype( a ), int&> );
      }


      According to Standard 11.5/3:




      [...] Given the type Ti designated by std::tuple_element<i, E>::type,
      variables are introduced with unique names ri of type “reference to
      Ti”
      initialized with the initializer (11.6.3), where the reference is
      an lvalue reference if the initializer is an lvalue
      and an rvalue
      reference otherwise. Each vi is the name of an lvalue of type Ti that
      refers to the object bound to ri; the referenced type is Ti.




      Here, i is 0 for the first element (int) and E is std::tuple<int>, so Ti has type std::tuple_element<0, std::tuple<int>>::type, i.e. int. Further ri (a in our case) has type "reference to Ti", i.e. lvalue reference int&, but not just int.
      What is wrong in that quote and why int type is deduced by both the compilers clang and gcc?










      share|improve this question















      This question already has an answer here:




      • structured bindings: when something looks like a reference and behaves similarly to a reference, but it's not a reference

        2 answers




      What is the type of a here?



      #include <iostream>
      #include <tuple>

      using namespace std;

      int main()
      {
      float x{};
      std::tuple<int> tpl( x );
      auto& [ a ] = tpl;
      static_assert( std::is_same_v< decltype( a ), int> );
      //static_assert( std::is_same_v< decltype( a ), int&> );
      }


      According to Standard 11.5/3:




      [...] Given the type Ti designated by std::tuple_element<i, E>::type,
      variables are introduced with unique names ri of type “reference to
      Ti”
      initialized with the initializer (11.6.3), where the reference is
      an lvalue reference if the initializer is an lvalue
      and an rvalue
      reference otherwise. Each vi is the name of an lvalue of type Ti that
      refers to the object bound to ri; the referenced type is Ti.




      Here, i is 0 for the first element (int) and E is std::tuple<int>, so Ti has type std::tuple_element<0, std::tuple<int>>::type, i.e. int. Further ri (a in our case) has type "reference to Ti", i.e. lvalue reference int&, but not just int.
      What is wrong in that quote and why int type is deduced by both the compilers clang and gcc?





      This question already has an answer here:




      • structured bindings: when something looks like a reference and behaves similarly to a reference, but it's not a reference

        2 answers








      c++ c++17 structured-bindings






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Dec 31 '18 at 10:55









      user3514538user3514538

      1,111618




      1,111618




      marked as duplicate by cpplearner, HolyBlackCat, llllllllll, T.C. c++
      Users with the  c++ badge can single-handedly close c++ questions as duplicates and reopen them as needed.

      StackExchange.ready(function() {
      if (StackExchange.options.isMobile) return;

      $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
      var $hover = $(this).addClass('hover-bound'),
      $msg = $hover.siblings('.dupe-hammer-message');

      $hover.hover(
      function() {
      $hover.showInfoMessage('', {
      messageElement: $msg.clone().show(),
      transient: false,
      position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
      dismissable: false,
      relativeToBody: true
      });
      },
      function() {
      StackExchange.helpers.removeMessages();
      }
      );
      });
      });
      Dec 31 '18 at 12:57


      This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









      marked as duplicate by cpplearner, HolyBlackCat, llllllllll, T.C. c++
      Users with the  c++ badge can single-handedly close c++ questions as duplicates and reopen them as needed.

      StackExchange.ready(function() {
      if (StackExchange.options.isMobile) return;

      $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
      var $hover = $(this).addClass('hover-bound'),
      $msg = $hover.siblings('.dupe-hammer-message');

      $hover.hover(
      function() {
      $hover.showInfoMessage('', {
      messageElement: $msg.clone().show(),
      transient: false,
      position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
      dismissable: false,
      relativeToBody: true
      });
      },
      function() {
      StackExchange.helpers.removeMessages();
      }
      );
      });
      });
      Dec 31 '18 at 12:57


      This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


























          2 Answers
          2






          active

          oldest

          votes


















          3














          It's true that the type of variable r0 is int&. But v0, here called a, is a different thing, the name of a structured binding, and is not technically a variable at all, just a different sort of name.



          So we need to look at the description of decltype, in [dcl.type.decltype]:




          For an expression e, the type denoted by decltype(e) is defined as follows:




          • if e is an unparenthesized id-expression naming a structured binding, decltype(e) is the referenced type as given in the specification of the structured binding declaration;




          So here the "referenced type" is just int.



          Of course, decltype((a)) is int& as we'd expect. decltype on a name without doubled parentheses is used to find out how a name is "declared", not how the name behaves, so it's not obvious that decltype(a) "should" be one thing or another, since a doesn't have a normal declaration. Though it is potentially a bit useful that given std::tuple<int, int&> t{0, n}; auto& [a, b] = t;, we have decltype(a) is int but decltype(b) is int&.






          share|improve this answer































            1














            Note




            the referenced type is Ti.




            For structured bindings, decltype yields the referenced type ([dcl.type.decltype]):




            if e is an unparenthesized id-expression naming a structured binding, decltype(e) is the referenced type as given in the specification of the structured binding declaration;







            share|improve this answer






























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              3














              It's true that the type of variable r0 is int&. But v0, here called a, is a different thing, the name of a structured binding, and is not technically a variable at all, just a different sort of name.



              So we need to look at the description of decltype, in [dcl.type.decltype]:




              For an expression e, the type denoted by decltype(e) is defined as follows:




              • if e is an unparenthesized id-expression naming a structured binding, decltype(e) is the referenced type as given in the specification of the structured binding declaration;




              So here the "referenced type" is just int.



              Of course, decltype((a)) is int& as we'd expect. decltype on a name without doubled parentheses is used to find out how a name is "declared", not how the name behaves, so it's not obvious that decltype(a) "should" be one thing or another, since a doesn't have a normal declaration. Though it is potentially a bit useful that given std::tuple<int, int&> t{0, n}; auto& [a, b] = t;, we have decltype(a) is int but decltype(b) is int&.






              share|improve this answer




























                3














                It's true that the type of variable r0 is int&. But v0, here called a, is a different thing, the name of a structured binding, and is not technically a variable at all, just a different sort of name.



                So we need to look at the description of decltype, in [dcl.type.decltype]:




                For an expression e, the type denoted by decltype(e) is defined as follows:




                • if e is an unparenthesized id-expression naming a structured binding, decltype(e) is the referenced type as given in the specification of the structured binding declaration;




                So here the "referenced type" is just int.



                Of course, decltype((a)) is int& as we'd expect. decltype on a name without doubled parentheses is used to find out how a name is "declared", not how the name behaves, so it's not obvious that decltype(a) "should" be one thing or another, since a doesn't have a normal declaration. Though it is potentially a bit useful that given std::tuple<int, int&> t{0, n}; auto& [a, b] = t;, we have decltype(a) is int but decltype(b) is int&.






                share|improve this answer


























                  3












                  3








                  3







                  It's true that the type of variable r0 is int&. But v0, here called a, is a different thing, the name of a structured binding, and is not technically a variable at all, just a different sort of name.



                  So we need to look at the description of decltype, in [dcl.type.decltype]:




                  For an expression e, the type denoted by decltype(e) is defined as follows:




                  • if e is an unparenthesized id-expression naming a structured binding, decltype(e) is the referenced type as given in the specification of the structured binding declaration;




                  So here the "referenced type" is just int.



                  Of course, decltype((a)) is int& as we'd expect. decltype on a name without doubled parentheses is used to find out how a name is "declared", not how the name behaves, so it's not obvious that decltype(a) "should" be one thing or another, since a doesn't have a normal declaration. Though it is potentially a bit useful that given std::tuple<int, int&> t{0, n}; auto& [a, b] = t;, we have decltype(a) is int but decltype(b) is int&.






                  share|improve this answer













                  It's true that the type of variable r0 is int&. But v0, here called a, is a different thing, the name of a structured binding, and is not technically a variable at all, just a different sort of name.



                  So we need to look at the description of decltype, in [dcl.type.decltype]:




                  For an expression e, the type denoted by decltype(e) is defined as follows:




                  • if e is an unparenthesized id-expression naming a structured binding, decltype(e) is the referenced type as given in the specification of the structured binding declaration;




                  So here the "referenced type" is just int.



                  Of course, decltype((a)) is int& as we'd expect. decltype on a name without doubled parentheses is used to find out how a name is "declared", not how the name behaves, so it's not obvious that decltype(a) "should" be one thing or another, since a doesn't have a normal declaration. Though it is potentially a bit useful that given std::tuple<int, int&> t{0, n}; auto& [a, b] = t;, we have decltype(a) is int but decltype(b) is int&.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Dec 31 '18 at 11:46









                  aschepleraschepler

                  52.1k579128




                  52.1k579128

























                      1














                      Note




                      the referenced type is Ti.




                      For structured bindings, decltype yields the referenced type ([dcl.type.decltype]):




                      if e is an unparenthesized id-expression naming a structured binding, decltype(e) is the referenced type as given in the specification of the structured binding declaration;







                      share|improve this answer




























                        1














                        Note




                        the referenced type is Ti.




                        For structured bindings, decltype yields the referenced type ([dcl.type.decltype]):




                        if e is an unparenthesized id-expression naming a structured binding, decltype(e) is the referenced type as given in the specification of the structured binding declaration;







                        share|improve this answer


























                          1












                          1








                          1







                          Note




                          the referenced type is Ti.




                          For structured bindings, decltype yields the referenced type ([dcl.type.decltype]):




                          if e is an unparenthesized id-expression naming a structured binding, decltype(e) is the referenced type as given in the specification of the structured binding declaration;







                          share|improve this answer













                          Note




                          the referenced type is Ti.




                          For structured bindings, decltype yields the referenced type ([dcl.type.decltype]):




                          if e is an unparenthesized id-expression naming a structured binding, decltype(e) is the referenced type as given in the specification of the structured binding declaration;








                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Dec 31 '18 at 11:27









                          cpplearnercpplearner

                          5,01521936




                          5,01521936















                              Popular posts from this blog

                              Mossoró

                              Error while reading .h5 file using the rhdf5 package in R

                              Pushsharp Apns notification error: 'InvalidToken'