Type of reference binding from std::tuple [duplicate]
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?
c++ c++17 structured-bindings
marked as duplicate by cpplearner, HolyBlackCat, llllllllll, T.C.
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.
add a comment |
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?
c++ c++17 structured-bindings
marked as duplicate by cpplearner, HolyBlackCat, llllllllll, T.C.
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.
add a comment |
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?
c++ c++17 structured-bindings
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
c++ c++17 structured-bindings
asked Dec 31 '18 at 10:55
user3514538user3514538
1,111618
1,111618
marked as duplicate by cpplearner, HolyBlackCat, llllllllll, T.C.
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.
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.
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
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 bydecltype(e)is defined as follows:
- if
eis 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&.
add a comment |
Note
the referenced type is Ti.
For structured bindings, decltype yields the referenced type ([dcl.type.decltype]):
if
eis an unparenthesized id-expression naming a structured binding,decltype(e)is the referenced type as given in the specification of the structured binding declaration;
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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 bydecltype(e)is defined as follows:
- if
eis 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&.
add a comment |
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 bydecltype(e)is defined as follows:
- if
eis 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&.
add a comment |
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 bydecltype(e)is defined as follows:
- if
eis 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&.
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 bydecltype(e)is defined as follows:
- if
eis 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&.
answered Dec 31 '18 at 11:46
aschepleraschepler
52.1k579128
52.1k579128
add a comment |
add a comment |
Note
the referenced type is Ti.
For structured bindings, decltype yields the referenced type ([dcl.type.decltype]):
if
eis an unparenthesized id-expression naming a structured binding,decltype(e)is the referenced type as given in the specification of the structured binding declaration;
add a comment |
Note
the referenced type is Ti.
For structured bindings, decltype yields the referenced type ([dcl.type.decltype]):
if
eis an unparenthesized id-expression naming a structured binding,decltype(e)is the referenced type as given in the specification of the structured binding declaration;
add a comment |
Note
the referenced type is Ti.
For structured bindings, decltype yields the referenced type ([dcl.type.decltype]):
if
eis an unparenthesized id-expression naming a structured binding,decltype(e)is the referenced type as given in the specification of the structured binding declaration;
Note
the referenced type is Ti.
For structured bindings, decltype yields the referenced type ([dcl.type.decltype]):
if
eis an unparenthesized id-expression naming a structured binding,decltype(e)is the referenced type as given in the specification of the structured binding declaration;
answered Dec 31 '18 at 11:27
cpplearnercpplearner
5,01521936
5,01521936
add a comment |
add a comment |