default value with reference variable

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • sam

    default value with reference variable

    Hi,

    I m wondering why I can't declare reference variable for default value
    in a function argument variable?

    eg.

    class A
    {
    void f(string &str="");
    };

    This causes compiled time error.

    Sam.
  • Achintya

    #2
    Re: default value with reference variable


    sam wrote:[color=blue]
    > Hi,
    >
    > I m wondering why I can't declare reference variable for default[/color]
    value[color=blue]
    > in a function argument variable?
    >
    > eg.
    >
    > class A
    > {
    > void f(string &str="");
    > };
    >
    > This causes compiled time error.
    >
    > Sam.[/color]

    Hi,

    You cannot declare a non-const reference to non-lvalue. The "string"
    that you are tring to declare doesn't have a l-value for the reference
    to get associated with. Hence...

    void f(const string& str="");

    will work fine in VC++ 6.0

    -vs_p...

    Comment

    • sam

      #3
      Re: default value with reference variable

      Achintya wrote:
      [color=blue]
      > sam wrote:
      >[color=green]
      >>Hi,
      >>
      >>I m wondering why I can't declare reference variable for default[/color]
      >
      > value
      >[color=green]
      >>in a function argument variable?
      >>
      >>eg.
      >>
      >>class A
      >>{
      >> void f(string &str="");
      >>};
      >>
      >>This causes compiled time error.
      >>
      >>Sam.[/color]
      >
      >
      > Hi,
      >
      > You cannot declare a non-const reference to non-lvalue. The "string"
      > that you are tring to declare doesn't have a l-value for the reference
      > to get associated with. Hence...
      >
      > void f(const string& str="");
      >[/color]
      Sorry, I m a bit confused with this. Why const string& works and string&
      doesn't?

      Sam.
      [color=blue]
      > will work fine in VC++ 6.0
      >
      > -vs_p...
      >[/color]

      Comment

      • Achintya

        #4
        Re: default value with reference variable


        sam wrote:[color=blue]
        > Achintya wrote:
        >[color=green]
        > > sam wrote:
        > >[color=darkred]
        > >>Hi,
        > >>
        > >>I m wondering why I can't declare reference variable for default[/color]
        > >
        > > value
        > >[color=darkred]
        > >>in a function argument variable?
        > >>
        > >>eg.
        > >>
        > >>class A
        > >>{
        > >> void f(string &str="");
        > >>};
        > >>
        > >>This causes compiled time error.
        > >>
        > >>Sam.[/color]
        > >
        > >
        > > Hi,
        > >
        > > You cannot declare a non-const reference to non-lvalue. The[/color][/color]
        "string"[color=blue][color=green]
        > > that you are tring to declare doesn't have a l-value for the[/color][/color]
        reference[color=blue][color=green]
        > > to get associated with. Hence...
        > >
        > > void f(const string& str="");
        > >[/color]
        > Sorry, I m a bit confused with this. Why const string& works and[/color]
        string&[color=blue]
        > doesn't?
        >
        > Sam.
        >[color=green]
        > > will work fine in VC++ 6.0
        > >
        > > -vs_p...
        > >[/color][/color]

        Yup...C++ compilers have two type of 'types' associated with C++
        variables and constants. The two types are l-value and r-value. l-value
        is associated with variables and r-value is associated with constants.
        For ex:

        a = 5; // is ok! but because 'a' is a variable and has a associated
        'l'ocation in memory hence it has l-value.
        5 = a; // is not OK because '5' is a numerical 'const' and doesn't have
        a l-value associated with it but it has a r-value

        .....and now in your situation the "" string is a const. hence that
        cannot be done.

        (For more explanation on l-value and r-value look:
        http://cplus.about.com/od/cprogrammi...def_lvalue.htm)

        -vs_p...

        Comment

        • ben

          #5
          Re: default value with reference variable

          Reference is supposed to be another name of an object. In order for that
          object to have a name it must be an "l-value". So what is l-value? Well, in
          the statement below:

          int phone_number = 21223345;
          string my_address = get_my_new_addr ess("my name is ben");

          phone_number and my_address are an l-values (left values); 21223345 and
          get_my_new_addr ess("my name is ben") are r-values (right values). A variable
          can be bound to either an l-value or an r-value. But as with references,
          they can only be bound to an l-value. Why? Simply think that an r-value
          doesn't have a name. Consider:

          int num = 2;
          int& ref_to_num = number; // OK, now ref_to_num is just another name of
          num

          int& ref_to_oops = 2; // Error, ref_to_oops is just another name
          of...er...em... nothing! It can't be done!
          ref_to_num = 2; // OK, same as num = 2;

          why must have a name? Consider:

          fruit& apple = fruit();

          Well, if the above example works, then apple will reference to a temporary
          object fruit(), which will be destroyed at the end of the statement. And the
          subsequent use of apple will be catastrophic!

          So a workaround of what you want to do might be:

          class A
          {
          static string default_str;
          void f(string& str = default_str); // default_str is an l-value
          };

          string A::default_str = "";


          Regards,
          Ben

          "sam" <root@localhost .com> wrote in message
          news:d6esm7$1b6 t$1@news.hgc.co m.hk...[color=blue]
          > Achintya wrote:
          >[color=green]
          > > sam wrote:
          > >[color=darkred]
          > >>Hi,
          > >>
          > >>I m wondering why I can't declare reference variable for default[/color]
          > >
          > > value
          > >[color=darkred]
          > >>in a function argument variable?
          > >>
          > >>eg.
          > >>
          > >>class A
          > >>{
          > >> void f(string &str="");
          > >>};
          > >>
          > >>This causes compiled time error.
          > >>
          > >>Sam.[/color]
          > >
          > >
          > > Hi,
          > >
          > > You cannot declare a non-const reference to non-lvalue. The "string"
          > > that you are tring to declare doesn't have a l-value for the reference
          > > to get associated with. Hence...
          > >
          > > void f(const string& str="");
          > >[/color]
          > Sorry, I m a bit confused with this. Why const string& works and string&
          > doesn't?
          >
          > Sam.
          >[color=green]
          > > will work fine in VC++ 6.0
          > >
          > > -vs_p...
          > >[/color][/color]


          Comment

          • Mark P

            #6
            Re: default value with reference variable

            ben wrote:[color=blue]
            >
            > why must have a name? Consider:
            >
            > fruit& apple = fruit();
            >
            > Well, if the above example works, then apple will reference to a temporary
            > object fruit(), which will be destroyed at the end of the statement. And the
            > subsequent use of apple will be catastrophic!
            >[/color]

            Helpful explanation. But I thought a reference bound to a temporary
            causes the lifetime of the temporary to extend to the lifetime of the
            reference?

            Comment

            • Ron Natalie

              #7
              Re: default value with reference variable

              Mark P wrote:[color=blue]
              > ben wrote:
              >[color=green]
              >>
              >> why must have a name? Consider:
              >>
              >> fruit& apple = fruit();
              >>
              >> Well, if the above example works, then apple will reference to a
              >> temporary
              >> object fruit(), which will be destroyed at the end of the statement.
              >> And the
              >> subsequent use of apple will be catastrophic!
              >>[/color]
              >
              > Helpful explanation. But I thought a reference bound to a temporary
              > causes the lifetime of the temporary to extend to the lifetime of the
              > reference?[/color]

              Yes, but you can only bind a rvalue to a const reference.
              The above is invalid.
              const fruit& = fruit();

              Comment

              • ben

                #8
                Re: default value with reference variable

                > Helpful explanation. But I thought a reference bound to a temporary[color=blue]
                > causes the lifetime of the temporary to extend to the lifetime of the
                > reference?[/color]

                It is a good idea. Indeed it is what is happening with heap-allocated
                objects:

                int ref_to_num = *(new int); // heap allocation
                ref_to_num = 1; // OK
                delete &ref_to_num; // End the life of object referenced by
                ref_to_num
                ref_to_num = 2; // undefined behavior, probably a crash

                But with local (stack allocated) variables, things are a little different.
                Object construction and destruction is always affiliated with stack
                management. So we have

                Fact 1. Temporary object must be popped from the stack.
                Fact 2. If an object is popped, it must be properly destroyed (by
                calling the destructor).

                Consequently, a temporary object must be destroyed before the next
                statement. If you want to explicitly management the object's lifetime with a
                reference, heap allocate the object.

                Regards
                Ben


                Comment

                • ben

                  #9
                  Re: default value with reference variable

                  > class A[color=blue]
                  > {
                  > void f(string &str="");
                  > };[/color]

                  Apart from my previous comments, the absence of const implies that the
                  function is gonna change the content of str. But if so a default value
                  doesn't make sense at all (making change to default value??) This is the
                  beauty of C++: if you design something seriously wrong, you get a compiler
                  error :)

                  Exactly what do you want to achieve with that code?

                  Ben


                  Comment

                  • Alan Johnson

                    #10
                    Re: default value with reference variable

                    ben wrote:[color=blue]
                    > Consequently, a temporary object must be destroyed before the next
                    > statement.[/color]

                    This is not correct. The compiler must guarantee that temporaries bound
                    to a const reference exist for the lifetime of the reference.

                    Comment

                    • Old Wolf

                      #11
                      Re: default value with reference variable

                      ben wrote:[color=blue][color=green]
                      > > Helpful explanation. But I thought a reference bound to a
                      > > temporary causes the lifetime of the temporary to extend
                      > > to the lifetime of the reference?[/color]
                      >
                      > It is a good idea. Indeed it is what is happening with
                      > heap-allocated objects:
                      >
                      > int ref_to_num = *(new int); // heap allocation
                      > ref_to_num = 1; // OK
                      > delete &ref_to_num; // End the life of object referenced by[/color]

                      Undefined behaviour -- ref_to_num is an automatic int,
                      you copied the value of it from the int created with (new int)
                      which has now been leaked.
                      [color=blue]
                      > ref_to_num = 2; // undefined behavior, probably a crash[/color]

                      Fine, actually.

                      Also, this example (even if you modified it to: int &ref_to_num)
                      has nothing to do with the original topic (extension of
                      lifetime of temporaries). *(new int) is not a temporary.
                      [color=blue]
                      > Fact 1. Temporary object must be popped from the stack.[/color]

                      There is no need for a 'stack' of any sort to be present.
                      So this is not really a fact.
                      [color=blue]
                      > Fact 2. If an object is popped, it must be properly destroyed (by
                      > calling the destructor).[/color]

                      You mean, if an object is deallocated it must be properly
                      destroyed. Which goes without saying. (Note: this 'fact' is
                      irrelevant, as temporary objects need not be deallocated,
                      see 'fact 1').
                      [color=blue]
                      > Consequently, a temporary object must be destroyed before the next
                      > statement.[/color]

                      That doesn't follow from anything you just said.
                      There would be no contradiction if temporary objects lasted
                      until the end of the current block, for example.
                      In fact, that is exactly what happens when the temporary
                      object gets bound to a reference.
                      [color=blue]
                      > If you want to explicitly management the object's lifetime
                      > with a reference, heap allocate the object.[/color]

                      Deeper and deeper into non-sequitur territory. If you want to
                      manage the lifetime with a reference.... use a reference!

                      Heap allocation has different semantics than automatic
                      allocation, as you have already noted.

                      Comment

                      Working...