Deducing LValue Reference type
There is quite a lot of discussion and clarification about template argument deduction and, in particular, reference collapsing and "universal references." This question goes through the relevant details: How does auto deduce type?, and this paper by Scott Meyers goes into even more detail and perhaps gives more examples and wider context: https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers, and his cppcon slides: http://www.aristeia.com/TalkNotes/C++TypeDeductionandWhyYouCareCppCon2014.pdf.
My question concerns the following code:
template <typename T> void f(T t) { t = 0; }
int main() {
int i{5};
int &ir{i};
f(ir);
cout << i << endl; // 5
f<decltype(ir)>(ir);
cout << i << endl; // 0
}
Why does my template function f
not deduce they type int &
? According to Scott Meyers' slides (slide 7) the fact that ir
is lvalue reference is simply ignored. That perfectly explains this behavior, but to perfectly explain that I've spent some time reading the reference and standard trying to find where it says something like:
If A is a reference type, the referred type is used by deduction.
This is what an old, offline version of the reference says (that I typically use), although it said it under the header Conversion Function Template, and I haven't found this wording in the standard. The closes I've found I think came from the rules for partial ordering of overloaded templates, but I don't believe it would apply here, even it was what I was looking for.
Is there somewhere in the standard that this behavior is specified, or is it implied by other behavior that I've overlooked? I would really like to be able to tell someone "that doesn't deduce type
int &
because of these words in the standard right here."c++ reference standards lvalue template-deduction
add a comment |
There is quite a lot of discussion and clarification about template argument deduction and, in particular, reference collapsing and "universal references." This question goes through the relevant details: How does auto deduce type?, and this paper by Scott Meyers goes into even more detail and perhaps gives more examples and wider context: https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers, and his cppcon slides: http://www.aristeia.com/TalkNotes/C++TypeDeductionandWhyYouCareCppCon2014.pdf.
My question concerns the following code:
template <typename T> void f(T t) { t = 0; }
int main() {
int i{5};
int &ir{i};
f(ir);
cout << i << endl; // 5
f<decltype(ir)>(ir);
cout << i << endl; // 0
}
Why does my template function f
not deduce they type int &
? According to Scott Meyers' slides (slide 7) the fact that ir
is lvalue reference is simply ignored. That perfectly explains this behavior, but to perfectly explain that I've spent some time reading the reference and standard trying to find where it says something like:
If A is a reference type, the referred type is used by deduction.
This is what an old, offline version of the reference says (that I typically use), although it said it under the header Conversion Function Template, and I haven't found this wording in the standard. The closes I've found I think came from the rules for partial ordering of overloaded templates, but I don't believe it would apply here, even it was what I was looking for.
Is there somewhere in the standard that this behavior is specified, or is it implied by other behavior that I've overlooked? I would really like to be able to tell someone "that doesn't deduce type
int &
because of these words in the standard right here."c++ reference standards lvalue template-deduction
1
On my mobile so I can't look it up but I believe the wording you are searching for is it ignores top level cv-ref qualifiers. To me this is the natural way to do this as the function looks likes it passes by value and it would be very surprising if for certain types it passes by reference.
– NathanOliver
Nov 22 '18 at 16:40
add a comment |
There is quite a lot of discussion and clarification about template argument deduction and, in particular, reference collapsing and "universal references." This question goes through the relevant details: How does auto deduce type?, and this paper by Scott Meyers goes into even more detail and perhaps gives more examples and wider context: https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers, and his cppcon slides: http://www.aristeia.com/TalkNotes/C++TypeDeductionandWhyYouCareCppCon2014.pdf.
My question concerns the following code:
template <typename T> void f(T t) { t = 0; }
int main() {
int i{5};
int &ir{i};
f(ir);
cout << i << endl; // 5
f<decltype(ir)>(ir);
cout << i << endl; // 0
}
Why does my template function f
not deduce they type int &
? According to Scott Meyers' slides (slide 7) the fact that ir
is lvalue reference is simply ignored. That perfectly explains this behavior, but to perfectly explain that I've spent some time reading the reference and standard trying to find where it says something like:
If A is a reference type, the referred type is used by deduction.
This is what an old, offline version of the reference says (that I typically use), although it said it under the header Conversion Function Template, and I haven't found this wording in the standard. The closes I've found I think came from the rules for partial ordering of overloaded templates, but I don't believe it would apply here, even it was what I was looking for.
Is there somewhere in the standard that this behavior is specified, or is it implied by other behavior that I've overlooked? I would really like to be able to tell someone "that doesn't deduce type
int &
because of these words in the standard right here."c++ reference standards lvalue template-deduction
There is quite a lot of discussion and clarification about template argument deduction and, in particular, reference collapsing and "universal references." This question goes through the relevant details: How does auto deduce type?, and this paper by Scott Meyers goes into even more detail and perhaps gives more examples and wider context: https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers, and his cppcon slides: http://www.aristeia.com/TalkNotes/C++TypeDeductionandWhyYouCareCppCon2014.pdf.
My question concerns the following code:
template <typename T> void f(T t) { t = 0; }
int main() {
int i{5};
int &ir{i};
f(ir);
cout << i << endl; // 5
f<decltype(ir)>(ir);
cout << i << endl; // 0
}
Why does my template function f
not deduce they type int &
? According to Scott Meyers' slides (slide 7) the fact that ir
is lvalue reference is simply ignored. That perfectly explains this behavior, but to perfectly explain that I've spent some time reading the reference and standard trying to find where it says something like:
If A is a reference type, the referred type is used by deduction.
This is what an old, offline version of the reference says (that I typically use), although it said it under the header Conversion Function Template, and I haven't found this wording in the standard. The closes I've found I think came from the rules for partial ordering of overloaded templates, but I don't believe it would apply here, even it was what I was looking for.
Is there somewhere in the standard that this behavior is specified, or is it implied by other behavior that I've overlooked? I would really like to be able to tell someone "that doesn't deduce type
int &
because of these words in the standard right here."c++ reference standards lvalue template-deduction
c++ reference standards lvalue template-deduction
asked Nov 22 '18 at 16:14
Nathan ChappellNathan Chappell
1277
1277
1
On my mobile so I can't look it up but I believe the wording you are searching for is it ignores top level cv-ref qualifiers. To me this is the natural way to do this as the function looks likes it passes by value and it would be very surprising if for certain types it passes by reference.
– NathanOliver
Nov 22 '18 at 16:40
add a comment |
1
On my mobile so I can't look it up but I believe the wording you are searching for is it ignores top level cv-ref qualifiers. To me this is the natural way to do this as the function looks likes it passes by value and it would be very surprising if for certain types it passes by reference.
– NathanOliver
Nov 22 '18 at 16:40
1
1
On my mobile so I can't look it up but I believe the wording you are searching for is it ignores top level cv-ref qualifiers. To me this is the natural way to do this as the function looks likes it passes by value and it would be very surprising if for certain types it passes by reference.
– NathanOliver
Nov 22 '18 at 16:40
On my mobile so I can't look it up but I believe the wording you are searching for is it ignores top level cv-ref qualifiers. To me this is the natural way to do this as the function looks likes it passes by value and it would be very surprising if for certain types it passes by reference.
– NathanOliver
Nov 22 '18 at 16:40
add a comment |
1 Answer
1
active
oldest
votes
There are no expressions of reference type in C++. The type of the variable ir
is int&
, but the type of the expression ir
is int
. This latter type is used for type deduction, since function arguments are always expressions (except in the special case of braced-init-lists).
See [expr.type]/1
If an expression initially has the type “reference to
T
” ([dcl.ref], [dcl.init.ref]), the type is adjusted toT
prior to any further analysis.
The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.
2
I feel a little silly that I missed that when I read it, but hot damn that resolves a lot of questions I had. I could kiss you, but please accept a sincere thank you instead.
– Nathan Chappell
Nov 22 '18 at 17:59
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53434825%2fdeducing-lvalue-reference-type%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
There are no expressions of reference type in C++. The type of the variable ir
is int&
, but the type of the expression ir
is int
. This latter type is used for type deduction, since function arguments are always expressions (except in the special case of braced-init-lists).
See [expr.type]/1
If an expression initially has the type “reference to
T
” ([dcl.ref], [dcl.init.ref]), the type is adjusted toT
prior to any further analysis.
The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.
2
I feel a little silly that I missed that when I read it, but hot damn that resolves a lot of questions I had. I could kiss you, but please accept a sincere thank you instead.
– Nathan Chappell
Nov 22 '18 at 17:59
add a comment |
There are no expressions of reference type in C++. The type of the variable ir
is int&
, but the type of the expression ir
is int
. This latter type is used for type deduction, since function arguments are always expressions (except in the special case of braced-init-lists).
See [expr.type]/1
If an expression initially has the type “reference to
T
” ([dcl.ref], [dcl.init.ref]), the type is adjusted toT
prior to any further analysis.
The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.
2
I feel a little silly that I missed that when I read it, but hot damn that resolves a lot of questions I had. I could kiss you, but please accept a sincere thank you instead.
– Nathan Chappell
Nov 22 '18 at 17:59
add a comment |
There are no expressions of reference type in C++. The type of the variable ir
is int&
, but the type of the expression ir
is int
. This latter type is used for type deduction, since function arguments are always expressions (except in the special case of braced-init-lists).
See [expr.type]/1
If an expression initially has the type “reference to
T
” ([dcl.ref], [dcl.init.ref]), the type is adjusted toT
prior to any further analysis.
The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.
There are no expressions of reference type in C++. The type of the variable ir
is int&
, but the type of the expression ir
is int
. This latter type is used for type deduction, since function arguments are always expressions (except in the special case of braced-init-lists).
See [expr.type]/1
If an expression initially has the type “reference to
T
” ([dcl.ref], [dcl.init.ref]), the type is adjusted toT
prior to any further analysis.
The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.
answered Nov 22 '18 at 16:49
BrianBrian
64.3k795182
64.3k795182
2
I feel a little silly that I missed that when I read it, but hot damn that resolves a lot of questions I had. I could kiss you, but please accept a sincere thank you instead.
– Nathan Chappell
Nov 22 '18 at 17:59
add a comment |
2
I feel a little silly that I missed that when I read it, but hot damn that resolves a lot of questions I had. I could kiss you, but please accept a sincere thank you instead.
– Nathan Chappell
Nov 22 '18 at 17:59
2
2
I feel a little silly that I missed that when I read it, but hot damn that resolves a lot of questions I had. I could kiss you, but please accept a sincere thank you instead.
– Nathan Chappell
Nov 22 '18 at 17:59
I feel a little silly that I missed that when I read it, but hot damn that resolves a lot of questions I had. I could kiss you, but please accept a sincere thank you instead.
– Nathan Chappell
Nov 22 '18 at 17:59
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53434825%2fdeducing-lvalue-reference-type%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
On my mobile so I can't look it up but I believe the wording you are searching for is it ignores top level cv-ref qualifiers. To me this is the natural way to do this as the function looks likes it passes by value and it would be very surprising if for certain types it passes by reference.
– NathanOliver
Nov 22 '18 at 16:40