Make auto become a reference if reference is returned by function












-1















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?










share|improve this question




















  • 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& 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











  • @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















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?










share|improve this question




















  • 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& 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











  • @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








-1








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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 28 '18 at 2:32









curiousguy

4,58623045




4,58623045










asked Nov 24 '18 at 17:09









user2741831user2741831

5881716




5881716








  • 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& 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











  • @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





    Use autp& maybe? Also note that you return a pointer in that function not a reference.

    – πάντα ῥεῖ
    Nov 24 '18 at 17:10








  • 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











  • @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












1 Answer
1






active

oldest

votes


















0














The C++ standard explains that auto is deducted from the initilizer value:




Declarations [dcl.spec.auto]/1: The auto and decltype(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






share|improve this answer

























    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%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









    0














    The C++ standard explains that auto is deducted from the initilizer value:




    Declarations [dcl.spec.auto]/1: The auto and decltype(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






    share|improve this answer






























      0














      The C++ standard explains that auto is deducted from the initilizer value:




      Declarations [dcl.spec.auto]/1: The auto and decltype(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






      share|improve this answer




























        0












        0








        0







        The C++ standard explains that auto is deducted from the initilizer value:




        Declarations [dcl.spec.auto]/1: The auto and decltype(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






        share|improve this answer















        The C++ standard explains that auto is deducted from the initilizer value:




        Declarations [dcl.spec.auto]/1: The auto and decltype(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







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 25 '18 at 19:58

























        answered Nov 24 '18 at 18:28









        ChristopheChristophe

        40.5k43576




        40.5k43576
































            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%2f53460520%2fmake-auto-become-a-reference-if-reference-is-returned-by-function%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