Deducing LValue Reference type












2















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."








share|improve this question


















  • 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


















2















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."








share|improve this question


















  • 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
















2












2








2


2






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."








share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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
















  • 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














1 Answer
1






active

oldest

votes


















1














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 to T 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.







share|improve this answer



















  • 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











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
});


}
});














draft saved

draft discarded


















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









1














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 to T 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.







share|improve this answer



















  • 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
















1














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 to T 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.







share|improve this answer



















  • 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














1












1








1







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 to T 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.







share|improve this answer













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 to T 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.








share|improve this answer












share|improve this answer



share|improve this answer










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














  • 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


















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Wiesbaden

Marschland

Dieringhausen