Make auto become a reference if reference is returned by function
I need the following code to work:
class Parent{
public:
virtual void fun(){throw 0};
};
class Child:public Parent{
public:
virtual void fun(){/*Success*/};
};
Parent& getChild(){
return *(new Child());
}
void main(){
auto child=getChild();
child.fun();
}
But for some reason auto
creates a Parent
instead of Parent &
which would correctly use the derived method. Is there a way to force auto
to create a reference instead of using a simple Instance?
c++ reference language-lawyer type-inference auto
|
show 1 more comment
I need the following code to work:
class Parent{
public:
virtual void fun(){throw 0};
};
class Child:public Parent{
public:
virtual void fun(){/*Success*/};
};
Parent& getChild(){
return *(new Child());
}
void main(){
auto child=getChild();
child.fun();
}
But for some reason auto
creates a Parent
instead of Parent &
which would correctly use the derived method. Is there a way to force auto
to create a reference instead of using a simple Instance?
c++ reference language-lawyer type-inference auto
1
Useautp&
maybe? Also note that you return a pointer in that function not a reference.
– πάντα ῥεῖ
Nov 24 '18 at 17:10
2
auto&
ordecltype(auto)
. "But for some reason auto creates a instead of which would correctly use the derived method" becauseauto
uses template type deduction.
– George
Nov 24 '18 at 17:11
@russian_symbols fixed
– user2741831
Nov 24 '18 at 17:16
@george that helps, thanks
– user2741831
Nov 24 '18 at 17:17
2
getChild
is a very poor design as the caller is unaware they need to free it
– M.M
Nov 25 '18 at 20:58
|
show 1 more comment
I need the following code to work:
class Parent{
public:
virtual void fun(){throw 0};
};
class Child:public Parent{
public:
virtual void fun(){/*Success*/};
};
Parent& getChild(){
return *(new Child());
}
void main(){
auto child=getChild();
child.fun();
}
But for some reason auto
creates a Parent
instead of Parent &
which would correctly use the derived method. Is there a way to force auto
to create a reference instead of using a simple Instance?
c++ reference language-lawyer type-inference auto
I need the following code to work:
class Parent{
public:
virtual void fun(){throw 0};
};
class Child:public Parent{
public:
virtual void fun(){/*Success*/};
};
Parent& getChild(){
return *(new Child());
}
void main(){
auto child=getChild();
child.fun();
}
But for some reason auto
creates a Parent
instead of Parent &
which would correctly use the derived method. Is there a way to force auto
to create a reference instead of using a simple Instance?
c++ reference language-lawyer type-inference auto
c++ reference language-lawyer type-inference auto
edited Nov 28 '18 at 2:32
curiousguy
4,58623045
4,58623045
asked Nov 24 '18 at 17:09
user2741831user2741831
5881716
5881716
1
Useautp&
maybe? Also note that you return a pointer in that function not a reference.
– πάντα ῥεῖ
Nov 24 '18 at 17:10
2
auto&
ordecltype(auto)
. "But for some reason auto creates a instead of which would correctly use the derived method" becauseauto
uses template type deduction.
– George
Nov 24 '18 at 17:11
@russian_symbols fixed
– user2741831
Nov 24 '18 at 17:16
@george that helps, thanks
– user2741831
Nov 24 '18 at 17:17
2
getChild
is a very poor design as the caller is unaware they need to free it
– M.M
Nov 25 '18 at 20:58
|
show 1 more comment
1
Useautp&
maybe? Also note that you return a pointer in that function not a reference.
– πάντα ῥεῖ
Nov 24 '18 at 17:10
2
auto&
ordecltype(auto)
. "But for some reason auto creates a instead of which would correctly use the derived method" becauseauto
uses template type deduction.
– George
Nov 24 '18 at 17:11
@russian_symbols fixed
– user2741831
Nov 24 '18 at 17:16
@george that helps, thanks
– user2741831
Nov 24 '18 at 17:17
2
getChild
is a very poor design as the caller is unaware they need to free it
– M.M
Nov 25 '18 at 20:58
1
1
Use
autp&
maybe? Also note that you return a pointer in that function not a reference.– πάντα ῥεῖ
Nov 24 '18 at 17:10
Use
autp&
maybe? Also note that you return a pointer in that function not a reference.– πάντα ῥεῖ
Nov 24 '18 at 17:10
2
2
auto&
or decltype(auto)
. "But for some reason auto creates a instead of which would correctly use the derived method" because auto
uses template type deduction.– George
Nov 24 '18 at 17:11
auto&
or decltype(auto)
. "But for some reason auto creates a instead of which would correctly use the derived method" because auto
uses template type deduction.– George
Nov 24 '18 at 17:11
@russian_symbols fixed
– user2741831
Nov 24 '18 at 17:16
@russian_symbols fixed
– user2741831
Nov 24 '18 at 17:16
@george that helps, thanks
– user2741831
Nov 24 '18 at 17:17
@george that helps, thanks
– user2741831
Nov 24 '18 at 17:17
2
2
getChild
is a very poor design as the caller is unaware they need to free it– M.M
Nov 25 '18 at 20:58
getChild
is a very poor design as the caller is unaware they need to free it– M.M
Nov 25 '18 at 20:58
|
show 1 more comment
1 Answer
1
active
oldest
votes
The C++ standard explains that auto is deducted from the initilizer value:
Declarations
[dcl.spec.auto]/1:
Theauto
anddecltype(auto)
type-specifiers are used to designate a placeholder type that will be
replaced later by deduction from an initializer.
Initializers
[dcl.init]/1:
A declarator can specify an initial
value for the identifier being declared.
So when you write the following declarators:
int t = f(10);
auto x = y;
auto child = getChild();
the right side is evaluated as an expression that yields a value. And this value is used to initialize the variable declared on the left side.
A value is not a reference. It's not like pointers and adresses. In an expression evaluation, whenever a reference is used, it's the referred value that is taken into consideration. You can see this with the following simple snippet:
int x=15;
int&y = x;
cout << x <<", " << y <<", " << &x<<endl;
cout << typeid(x).name() <<", " << typeid(y).name() <<", " << typeid(&x).name() <<endl;
In your case, the expression value is therefore a Parent
and not Parent &
. This is why your auto
will be deduced to have the Parent
type.
The C++ standard does however not consider all the values in the same manner. In [basic.lval]
it makes an important distinction between different kind of values, which can be lvalues, xvalues and prvalues. In your case getChild()
evaluates to an lvalue that is the object to which you referred and not some temporary copy of it.
When you have such an lvalue, you can create a reference to it:
[dcl.ref]
/2: A reference type that is declared using&
is called an
lvalue reference, (...)
But you need to do this explicitly by saying that your auto should be a reference:
auto &child = getChild();
Edit: More infos on the way auto works: Herb Sutter's GotW blog
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%2f53460520%2fmake-auto-become-a-reference-if-reference-is-returned-by-function%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
The C++ standard explains that auto is deducted from the initilizer value:
Declarations
[dcl.spec.auto]/1:
Theauto
anddecltype(auto)
type-specifiers are used to designate a placeholder type that will be
replaced later by deduction from an initializer.
Initializers
[dcl.init]/1:
A declarator can specify an initial
value for the identifier being declared.
So when you write the following declarators:
int t = f(10);
auto x = y;
auto child = getChild();
the right side is evaluated as an expression that yields a value. And this value is used to initialize the variable declared on the left side.
A value is not a reference. It's not like pointers and adresses. In an expression evaluation, whenever a reference is used, it's the referred value that is taken into consideration. You can see this with the following simple snippet:
int x=15;
int&y = x;
cout << x <<", " << y <<", " << &x<<endl;
cout << typeid(x).name() <<", " << typeid(y).name() <<", " << typeid(&x).name() <<endl;
In your case, the expression value is therefore a Parent
and not Parent &
. This is why your auto
will be deduced to have the Parent
type.
The C++ standard does however not consider all the values in the same manner. In [basic.lval]
it makes an important distinction between different kind of values, which can be lvalues, xvalues and prvalues. In your case getChild()
evaluates to an lvalue that is the object to which you referred and not some temporary copy of it.
When you have such an lvalue, you can create a reference to it:
[dcl.ref]
/2: A reference type that is declared using&
is called an
lvalue reference, (...)
But you need to do this explicitly by saying that your auto should be a reference:
auto &child = getChild();
Edit: More infos on the way auto works: Herb Sutter's GotW blog
add a comment |
The C++ standard explains that auto is deducted from the initilizer value:
Declarations
[dcl.spec.auto]/1:
Theauto
anddecltype(auto)
type-specifiers are used to designate a placeholder type that will be
replaced later by deduction from an initializer.
Initializers
[dcl.init]/1:
A declarator can specify an initial
value for the identifier being declared.
So when you write the following declarators:
int t = f(10);
auto x = y;
auto child = getChild();
the right side is evaluated as an expression that yields a value. And this value is used to initialize the variable declared on the left side.
A value is not a reference. It's not like pointers and adresses. In an expression evaluation, whenever a reference is used, it's the referred value that is taken into consideration. You can see this with the following simple snippet:
int x=15;
int&y = x;
cout << x <<", " << y <<", " << &x<<endl;
cout << typeid(x).name() <<", " << typeid(y).name() <<", " << typeid(&x).name() <<endl;
In your case, the expression value is therefore a Parent
and not Parent &
. This is why your auto
will be deduced to have the Parent
type.
The C++ standard does however not consider all the values in the same manner. In [basic.lval]
it makes an important distinction between different kind of values, which can be lvalues, xvalues and prvalues. In your case getChild()
evaluates to an lvalue that is the object to which you referred and not some temporary copy of it.
When you have such an lvalue, you can create a reference to it:
[dcl.ref]
/2: A reference type that is declared using&
is called an
lvalue reference, (...)
But you need to do this explicitly by saying that your auto should be a reference:
auto &child = getChild();
Edit: More infos on the way auto works: Herb Sutter's GotW blog
add a comment |
The C++ standard explains that auto is deducted from the initilizer value:
Declarations
[dcl.spec.auto]/1:
Theauto
anddecltype(auto)
type-specifiers are used to designate a placeholder type that will be
replaced later by deduction from an initializer.
Initializers
[dcl.init]/1:
A declarator can specify an initial
value for the identifier being declared.
So when you write the following declarators:
int t = f(10);
auto x = y;
auto child = getChild();
the right side is evaluated as an expression that yields a value. And this value is used to initialize the variable declared on the left side.
A value is not a reference. It's not like pointers and adresses. In an expression evaluation, whenever a reference is used, it's the referred value that is taken into consideration. You can see this with the following simple snippet:
int x=15;
int&y = x;
cout << x <<", " << y <<", " << &x<<endl;
cout << typeid(x).name() <<", " << typeid(y).name() <<", " << typeid(&x).name() <<endl;
In your case, the expression value is therefore a Parent
and not Parent &
. This is why your auto
will be deduced to have the Parent
type.
The C++ standard does however not consider all the values in the same manner. In [basic.lval]
it makes an important distinction between different kind of values, which can be lvalues, xvalues and prvalues. In your case getChild()
evaluates to an lvalue that is the object to which you referred and not some temporary copy of it.
When you have such an lvalue, you can create a reference to it:
[dcl.ref]
/2: A reference type that is declared using&
is called an
lvalue reference, (...)
But you need to do this explicitly by saying that your auto should be a reference:
auto &child = getChild();
Edit: More infos on the way auto works: Herb Sutter's GotW blog
The C++ standard explains that auto is deducted from the initilizer value:
Declarations
[dcl.spec.auto]/1:
Theauto
anddecltype(auto)
type-specifiers are used to designate a placeholder type that will be
replaced later by deduction from an initializer.
Initializers
[dcl.init]/1:
A declarator can specify an initial
value for the identifier being declared.
So when you write the following declarators:
int t = f(10);
auto x = y;
auto child = getChild();
the right side is evaluated as an expression that yields a value. And this value is used to initialize the variable declared on the left side.
A value is not a reference. It's not like pointers and adresses. In an expression evaluation, whenever a reference is used, it's the referred value that is taken into consideration. You can see this with the following simple snippet:
int x=15;
int&y = x;
cout << x <<", " << y <<", " << &x<<endl;
cout << typeid(x).name() <<", " << typeid(y).name() <<", " << typeid(&x).name() <<endl;
In your case, the expression value is therefore a Parent
and not Parent &
. This is why your auto
will be deduced to have the Parent
type.
The C++ standard does however not consider all the values in the same manner. In [basic.lval]
it makes an important distinction between different kind of values, which can be lvalues, xvalues and prvalues. In your case getChild()
evaluates to an lvalue that is the object to which you referred and not some temporary copy of it.
When you have such an lvalue, you can create a reference to it:
[dcl.ref]
/2: A reference type that is declared using&
is called an
lvalue reference, (...)
But you need to do this explicitly by saying that your auto should be a reference:
auto &child = getChild();
Edit: More infos on the way auto works: Herb Sutter's GotW blog
edited Nov 25 '18 at 19:58
answered Nov 24 '18 at 18:28
ChristopheChristophe
40.5k43576
40.5k43576
add a comment |
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%2f53460520%2fmake-auto-become-a-reference-if-reference-is-returned-by-function%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
Use
autp&
maybe? Also note that you return a pointer in that function not a reference.– πάντα ῥεῖ
Nov 24 '18 at 17:10
2
auto&
ordecltype(auto)
. "But for some reason auto creates a instead of which would correctly use the derived method" becauseauto
uses template type deduction.– George
Nov 24 '18 at 17:11
@russian_symbols fixed
– user2741831
Nov 24 '18 at 17:16
@george that helps, thanks
– user2741831
Nov 24 '18 at 17:17
2
getChild
is a very poor design as the caller is unaware they need to free it– M.M
Nov 25 '18 at 20:58