CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 31
  1. #16
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: Can operator= assign const member?

    Good grief. I was playing about trying to make sense of the relevant section in the standard (5.2.11), and I got the process to work, so I thought I'd let people know. I didn't expect the Spanish Inquisition...

    And yes, the swap trick is about exception safety. I could have simplified the code, but I routinely write my assignment operators that way, so that's how it got written. If you can't see why it's exception safe, then I suggest you read Exceptional C++ for all the gory details.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  2. #17
    Join Date
    Mar 2003
    Location
    India {Mumbai};
    Posts
    3,871

    Re: Can operator= assign const member?

    Quote Originally Posted by darwen
    You could use the 'mutable' keyword on your const member. It only works for members though.
    Are you sure that you can use 'const' and 'mutable' specifiers on same data-member of class?
    Code:
    class See
    	{
    		mutable const x;
    	};
    Quote Originally Posted by VC6 Compiler
    e:\ajay....(98) : error C2071: 'x' : illegal storage class
    Quote Originally Posted by VC7.1 Compiler
    e:\Ajay\...(98) : error C2071: 'See::x' : illegal storage class
    My latest article: Explicating the new C++ standard (C++0x)

    Do rate the posts you find useful.

  3. #18
    Join Date
    May 2004
    Location
    Norway
    Posts
    655

    Re: Can operator= assign const member?

    Quote Originally Posted by Graham
    I didn't expect the Spanish Inquisition...
    Nobody expects the Spanish Inquisition!
    Insert entertaining phrase here

  4. #19
    Join Date
    Jun 2001
    Location
    Switzerland
    Posts
    4,443

    Re: Can operator= assign const member?

    Quote Originally Posted by Ajay Vijay
    Are you sure that you can use 'const' and 'mutable' specifiers on same data-member of class?
    No. Either const or mutable. "Mutable" means that a data member may be changed on a const object -- this is not quite related to the current thread. Suppose you have a polygon class with a const getter GetSurface(). The getter computes the surface and caches it in a data member prior returning it. Now it makes sense to have that data member 'mutable', to allow a 'const polygon' to cache. Semantically the mutable member shall not be part of the visible state of the object.
    Gabriel, CodeGuru moderator

    Forever trusting who we are
    And nothing else matters
    - Metallica

    Learn about the advantages of std::vector.

  5. #20
    Join Date
    Mar 2003
    Location
    India {Mumbai};
    Posts
    3,871

    Re: Can operator= assign const member?

    Thanks Gabriel, I am quite aware of that technique. My post was with the text posted by Graham:
    Quote Originally Posted by Graham
    You could use the 'mutable' keyword on your const member...
    My latest article: Explicating the new C++ standard (C++0x)

    Do rate the posts you find useful.

  6. #21
    Join Date
    Sep 2004
    Posts
    519

    Re: Can operator= assign const member?

    If one starts to add keywords like mutable to the members why not remove the const all together?

    The problem I see with this is that the assignment operator breaks the semantics of the const variable.

    If you want to support assignment then the member variable shouldn't be const.

    Now, you might not have control over the source code and in that case I think const_cast will work fine in most cases (together with a comment why the const_cast is there).

    There is a risk with modern compilers that they place const variables in protected memory but I haven't run into that myself yet.

    If you want to use const to protect against accidental modification (a noble cause) then I would consider making a template wrapper class that doesn't allow modifcation but do allow swapping and copy construction (with a non-throwing swap and a copy-construction one can as demonstrated above implement assignment)

    Then there is the possibility to disallow assignment and use smart pointers.

    So in order to be able to offer a better advise I think the OP should provide more background information.

  7. #22
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: Can operator= assign const member?

    Ajay: I never said that...
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  8. #23
    Join Date
    Apr 2005
    Posts
    15

    Re: Can operator= assign const member?

    Hi Graham - you're not getting the Spanish Inquisition from me! I appreciate all the input and am happy to have learned the swap construct. I'll add that book to my reading list.

  9. #24
    Join Date
    Jun 2001
    Location
    Switzerland
    Posts
    4,443

    Re: Can operator= assign const member?

    I think that Graham tends to "get the Spanish Inquisition" because many people can't wait to "catch" him making a mistake. That, because he very rarely makes any...
    Gabriel, CodeGuru moderator

    Forever trusting who we are
    And nothing else matters
    - Metallica

    Learn about the advantages of std::vector.

  10. #25
    Join Date
    Sep 2004
    Posts
    519

    Re: Can operator= assign const member?

    n.marier: If you're interested in exception safety the book 'Exceptional C++' (http://www.gotw.ca/publications/xc++.htm) goes into great depths to explain why and how some common techniques (such as implementing assignment as copy-and-swap) works.

    Plus much more.

    It's an "exceptional" book.
    Last edited by marten_range; April 6th, 2005 at 09:50 AM. Reason: Clarification

  11. #26
    Join Date
    Mar 2003
    Location
    Germany, K-Town
    Posts
    578

    Re: Can operator= assign const member?

    Not that anyone cares, but terrashop.de had it in pdf-format for 2.50€, in their ebook-of-the-week section. Looks like that was a darn good deal
    - Matthias

    "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off." - Bjarne Stroustrup

  12. #27
    Join Date
    May 2009
    Posts
    2,413

    Re: Can operator= assign const member?

    Quote Originally Posted by marten_range View Post
    The problem I see with this is that the assignment operator breaks the semantics of the const variable.

    If you want to support assignment then the member variable shouldn't be const.
    I know this is a zombie thread but I find it quite interesting so I reply anyway.

    Many felt the strict physical interpretation of C++ constness was too rigid and so the mutable keyword was introduced. It allows for a more logical interpretation of constness and in my view assignment of const objects falls well into this category. I can't see why it should be considered more malign than using the mutable keyword really.

    Say you have a small mutable value object like this,
    Code:
    struct Mutable {
        int a;
        Mutable() : a(0) {}
        explicit Mutable(int a) : a(a) {}
    };
    If you want to make it immutable a natural approach would be to simply declare 'a' const,

    Code:
    struct Immutable {
       const int a; // variable is declared const
       Immutable() : a(0) {}
       explicit Immutable(int a) : a(a) {}
    };
    Now the 'a' variable cannot be changed after object creation which is what you want. What you probably don't want is that the object is forever stuck in the variable where it was created. You cannot do this,

    Code:
    Immutable m1(43);
    Immutable m2(7);
    m2 = m1; // not allowed
    m1 = m2; // not allowed
    The m1 and m2 variables behave like if they were declared const which they aren't so this definately is more constness than you bargained for.

    To overcome this you have two options. One is to supply an assignment operator which casts away const, like this,
    Code:
    struct Immutable1 {
        const int a;
        Immutable1() : a(0) {}
        explicit Immutable1(int a) : a(a) {}
        Immutable1 operator=(const Immutable1& rhs) { 
            *(const_cast<int*>(&a)) = rhs.a;  // cast away const
            return *this;
        }
    };
    Now objects are immutable so the 'a' variable can never change after creation but objects can still be copied and assigned to other variables.

    The other option is to make 'a' private and non-const and access it via a const getter function like,
    Code:
    struct Immutable2 {
        int a() const {   // a getter
            return a_;
        }
        Immutable2() : a_(0) {}
        explicit Immutable2(int a) : a_(a) {}
    private:
        int a_; // private non-const
    };
    Well, before I came upon this thread I probably would've preferred the second approach but I'm not so sure anymore. Okay, the cast in the first approach is ugly but it has the advantage of the 'a' variable actually being declared const and thus safer from any accidental modification.

    What do you think? Maybe there's some third option?
    Last edited by nuzzle; December 31st, 2010 at 09:05 AM.

  13. #28
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Can operator= assign const member?

    Quote Originally Posted by nuzzle View Post
    To overcome this you have two options. One is to supply an assignment operator which casts away const, like this,
    As mentioned above, this is undefined behavior according to the standard.
    Quote Originally Posted by nuzzle View Post
    Now objects are immutable so the 'a' variable can never change after creation but objects can still be copied and assigned to other variables.
    The value of 'a' can change, namely through the assignment operator. Which is exactly what is bad about this IMO. If I see a member variable is const, I expect it won't change, because that is exactly what it means. So IMO declaring a variable as const when it actually can change isn't an advantage, but a bug waiting to happen.
    Quote Originally Posted by nuzzle View Post
    What do you think? Maybe there's some third option?
    A third option could be to check in run-time whether the value of the const member variables is equal.
    Code:
    struct Foo
    {
        int m_a;
        const int m_b;
        explicit Foo(int b) : m_b(b) {}
        Foo& operator =(const Foo& that) {
            if (m_b != that.m_b) {
                throw std::invalid_argument("Cannot assign incompatible Foo.");
            }
            m_a = that.m_a;
        }
    };
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  14. #29
    Join Date
    May 2009
    Posts
    2,413

    Re: Can operator= assign const member?

    Quote Originally Posted by D_Drmmr View Post
    As mentioned above, this is undefined behavior according to the standard.
    Two posters recommend this solution and one is unsure. Now you indicate you're sure that,

    *(const_cast<int*>(&a)) = rhs.a; // cast away const

    leads to undefined behavior according to the standard. Could you please point out the section you're referring to. If that's true then this "solution" is out of question of course.

    If I see a member variable is const, I expect it won't change, because that is exactly what it means. So IMO declaring a variable as const when it actually can change isn't an advantage, but a bug waiting to happen.
    Well, the 'a' variable itself of a created object never changes. Both Immutable1 and Immutable2 are immutable indeed. It's just that the far-reaching restrictions of physical constness are somewhat relaxed (just like they are when mutable is used). You still have logical constness of the 'a' variable. It can never change.

    I find it both unexpected and unwanted that just because you declare a variable const then objects cannot be freely assigned anymore. Consider my Immutable2 example. You cannot declare the 'a_' variable const although it's a private constant that should never change after object creation. Because if you do, Immutable2 variables will behave as if they were declared const although they aren't.

    So I think physical constness of variables induces an unhealthy coupling between variables and values. One interesting suggesting to resolve this at the language level was presented in this thread,

    Code:
    struct Suggestion {
       mutable const a;
    };
    It would mean that although 'a' never changes once a Suggestion object is created, it's still possible to copy Suggestion objects between Suggestion variables.

    Well, it looks like I'm back to the Immutable2 solution. Especially if Immutable1 gives undefined behavior as you claim.
    Last edited by nuzzle; January 1st, 2011 at 04:36 AM.

  15. #30
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Can operator= assign const member?

    Quote Originally Posted by nuzzle View Post
    Two posters recommend this solution and one is unsure. Now you indicate you're sure that,

    *(const_cast<int*>(&a)) = rhs.a; // cast away const

    leads to undefined behavior according to the standard. Could you please point out the section you're referring to. If that's true then this "solution" is out of question of course.
    All I happen to have here is the draft n2798, but I guess that'll do. Section 7.1.6.1 states in point 4:
    Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.
    It is followed by an example:
    Code:
    const int* ciq = new const int (3); // initialized as required
    int* iq = const_cast<int*>(ciq);    // cast required
    *iq = 4;                            // undefined: modifies a const object
    Quote Originally Posted by nuzzle View Post
    Well, the 'a' variable itself of a created object never changes. Both Immutable1 and Immutable2 are immutable indeed. It's just that the far-reaching restrictions of physical constness are somewhat relaxed (just like they are when mutable is used). You still have logical constness of the 'a' variable. It can never change.
    I don't understand what you mean. If we take your example that uses const_cast as a valid program (e.g. by assuming a compiler extension that allows this), then the value of 'a' can change.
    Code:
    Immutable1 m1(43);
    Immutable1 m2(7);
    m2 = m1;
    Before the assignment the value of m2.a is 7, after the assignment it is 43. That means it changed. That's bad, because 'a' was declared const.
    Quote Originally Posted by nuzzle View Post
    I find it both unexpected and unwanted that just because you declare a variable const then objects cannot be freely assigned anymore. Consider my Immutable2 example. You cannot declare the 'a_' variable const although it's a private constant that should never change after object creation. Because if you do, Immutable2 variables will behave as if they were declared const although they aren't.
    In this case, in a sense yes, but that is only because there is only one member variable. That's why I gave an example with two member variables.
    Quote Originally Posted by nuzzle View Post
    So I think physical constness of variables induces an unhealthy coupling between variables and values. One interesting suggesting to resolve this at the language level was presented in this thread,

    Code:
    struct Suggestion {
       mutable const a;
    };
    It would mean that although 'a' never changes once a Suggestion object is created, it's still possible to copy Suggestion objects between Suggestion variables.
    Besides the contradiction in your last sentense, I don't see what's the point. What's the difference with having a non-const member variable? If the idea is that only the copy assignment operator of Suggestion is allowed to change the value of a, then what's the added value over the Immutable2 example you gave?
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

Page 2 of 3 FirstFirst 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured