Value restriction

Discussion in 'C++' started by JKop, Jul 13, 2004.

  1. JKop

    JKop Guest

    Here's a little pickle I've been pondering over. I've simplified it down for
    posting, here goes:


    Consider a function as simple (and as dumb) as the following:


    bool IsAfter1998(Year year)
    {
    return (year > 1998);
    }



    So let's define the "Year" type. We start off with:


    typedef int Year;


    I want to restrict the value of a "Year" to not being 0 ( 1 BC is followed
    by 1 AD). I've started off with this:


    class Year
    {
    private:

    int data;

    void Set(int year)
    {
    if ( year == 0 ) throw bad_year();

    data = year;
    }

    public:

    class bad_year {};

    explicit Year(int year = 1)
    {
    Set(year);
    }

    Year& operator=(Year year)
    {
    Set(year);

    return *this;
    }

    operator int()
    {
    return data;
    }

    };


    I figured a lot of people have probably done something like this before. So
    can anyone suggest any suitable alternatives or maybe tweek my code a
    little?

    Particularly with my code, I realize that one can't do the following:

    Year year;

    ++year;


    -JKop
    JKop, Jul 13, 2004
    #1
    1. Advertising

  2. JKop wrote:
    > Here's a little pickle I've been pondering over. I've simplified it down for
    > posting, here goes:
    >
    >
    > Consider a function as simple (and as dumb) as the following:
    >
    >
    > bool IsAfter1998(Year year)
    > {
    > return (year > 1998);
    > }
    >
    >
    >
    > So let's define the "Year" type. We start off with:
    >
    >
    > typedef int Year;
    >
    >
    > I want to restrict the value of a "Year" to not being 0 ( 1 BC is followed
    > by 1 AD). I've started off with this:
    >
    >
    > class Year
    > {
    > private:
    >
    > int data;
    >
    > void Set(int year)
    > {
    > if ( year == 0 ) throw bad_year();
    >
    > data = year;
    > }
    >
    > public:
    >
    > class bad_year {};
    >
    > explicit Year(int year = 1)
    > {
    > Set(year);
    > }
    >
    > Year& operator=(Year year)
    > {
    > Set(year);
    >
    > return *this;
    > }
    >
    > operator int()
    > {
    > return data;
    > }
    >
    > };
    >
    >
    > I figured a lot of people have probably done something like this before. So
    > can anyone suggest any suitable alternatives or maybe tweek my code a
    > little?
    >
    > Particularly with my code, I realize that one can't do the following:
    >
    > Year year;
    >
    > ++year;
    >
    >
    > -JKop


    I love integers:
    Year sci_fic;
    sci_fic = -20;
    sci_fic++;
    sci_fic--;
    sci_fic /= 40;

    By the way, you could use _unsigned_int_ if you
    want the compiler to restrict the year to postive
    values.

    One idea is to have an inline function that validates
    a year:
    inline Validate_Year(unsigned int year)
    {
    if (year < 1)
    throw Your_Favorite_Exception();
    return;
    }

    I believe this would have minimal impact since it
    is declared as inline.

    I don't see any need to complicate the code by
    creating a separate year class. Nor, IMHO, any
    special reason to make the year a separate type.


    --
    Thomas Matthews

    C++ newsgroup welcome message:
    http://www.slack.net/~shiva/welcome.txt
    C++ Faq: http://www.parashift.com/c -faq-lite
    C Faq: http://www.eskimo.com/~scs/c-faq/top.html
    alt.comp.lang.learn.c-c++ faq:
    http://www.raos.demon.uk/acllc-c /faq.html
    Other sites:
    http://www.josuttis.com -- C++ STL Library book
    Thomas Matthews, Jul 13, 2004
    #2
    1. Advertising

  3. JKop

    red floyd Guest

    Thomas Matthews wrote:

    > By the way, you could use _unsigned_int_ if you
    > want the compiler to restrict the year to postive
    > values.


    He doesn't want to restrict to positive, he wants to restrict to
    *NON-ZERO*. Slightly different.
    red floyd, Jul 13, 2004
    #3
  4. JKop

    Ron Natalie Guest

    "JKop" <> wrote in message news:tVXIc.4517$...
    >
    > Here's a little pickle I've been pondering over. I've simplified it down for
    > posting, here goes:
    > > typedef int Year;

    >
    >

    Your copy constructor seems a bit spurious. If you can't construct an invalid year
    object, how could you ever get an invalid one to copy?

    I detest implicit conversion operators.

    Yes, you are going to have to define mathematic operators. Think about how pointers/iterators
    work. The subtraction of two years is some integral type, but years should not otherwise implicitly
    convert to/from numerics.
    Ron Natalie, Jul 13, 2004
    #4
  5. JKop

    JKop Guest

    Ron Natalie posted:


    > Your copy constructor seems a bit spurious. If you

    can't construct an
    > invalid year object, how could you ever get an invalid

    one to copy?


    If by spurious you mean absent, then yes.

    What you think of my assignment operator?


    > I detest implicit conversion operators.
    >
    > Yes, you are going to have to define mathematic

    operators. Think
    > about how pointers/iterators work. The subtraction of

    two years is
    > some integral type, but years should not otherwise

    implicitly convert
    > to/from numerics.


    I disagree: a year *is* a number. Anyway, that was just an
    example.

    I wonder if it'd be appropriate to increment -1 to 1?

    Year& operator++()
    {
    return ( data == -1 ? data = 1 : data += 1 );
    }

    Year& operator--()
    {
    return ( data == 1 ? data = -1 : data -= 1 );
    }


    -JKop
    JKop, Jul 14, 2004
    #5
  6. JKop

    JKop Guest


    > Year& operator++()
    > {
    > return ( data == -1 ? data = 1 : data += 1 );
    > }
    >
    > Year& operator--()
    > {
    > return ( data == 1 ? data = -1 : data -= 1 );
    > }


    Opps!


    Year& operator++()
    {
    data == -1 ? data = 1 : data += 1 ;

    return *this;
    }

    Year& operator--()
    {
    data == 1 ? data = -1 : data -= 1 ;

    return *this;
    }


    -JKop
    JKop, Jul 14, 2004
    #6
  7. JKop wrote:
    >
    > Ron Natalie posted:
    >
    > > Your copy constructor seems a bit spurious. If you

    > can't construct an
    > > invalid year object, how could you ever get an invalid

    > one to copy?
    >
    > If by spurious you mean absent, then yes.
    >
    > What you think of my assignment operator?


    I think it is not needed.
    One of the premises is that it is impossible to create
    an invalid Year object. So whetever is passed to the assignment
    operator *must* be a valid Year object. Thus the test if it
    is valid is not neccessary. A simple assignment of the data
    member is sufficient. But this is what the compiler generated
    operator does anyway, so it is better to let the compiler take
    care of op= instead of writing your own.

    >
    > I wonder if it'd be appropriate to increment -1 to 1?


    Sure, why not.

    >
    > Year& operator++()
    > {
    > return ( data == -1 ? data = 1 : data += 1 );
    > }


    But not like this.
    it needs to return *this.

    >
    > Year& operator--()
    > {
    > return ( data == 1 ? data = -1 : data -= 1 );
    > }


    Same. return *this;

    With other operators there is a problem on the horizon.

    The problem I see is this: What is the return value of op- ?
    Is it Year? Well, in every day speaking we say so, but is that really
    true. Is a YearSpan the same thing as a Year?
    Lets take the conservative approach and say: No. The result of
    subtracting 1960 from 1940 is not a Year object, but a YearSpan object.
    That makes sense, since adding 1940 with 1980 doesn't really make sense.
    But adding 40 years (a YearSpan object) to 1980 makes perfectly sense.

    What about op* and op- ?
    Does it make sense to calulate 1940 * 1980 ?
    I would say no. But it would make sense to allow op/ and op* for
    a YearSpan object. 1940 + 2 * 40_years seems reasonable: add 2 times
    the amount of 40 years (as YearSpan) to 1940.

    --
    Karl Heinz Buchegger
    Karl Heinz Buchegger, Jul 14, 2004
    #7
  8. JKop

    JKop Guest

    Have the C++ dudes considered "allowing" the following?:


    class Year : public int
    {
    // Hijack the constructor and all the = operators, += -= *=
    /= etc.

    }


    Ofcourse you wouldn't have any virtual members, but that
    wouldn't be a problem:

    bool IsAfter1998(Year year)
    {
    return (year > 1998)
    }


    I hear in other languages you can inherit from the
    intrinsic types... no?

    Actually, right now this moment I've thought of an
    alternative:

    class Int
    {
    //All sorts of operators

    operator int+() //...

    };


    class Year : public Int ...


    Just create an Int class that acts EXACTLY like an int...
    (but maybe give it defined overflow behavior ;-) )


    -JKop
    JKop, Jul 14, 2004
    #8
  9. JKop

    JKop Guest

    > operator int+() //...

    TYPO

    operator int()


    -JKop
    JKop, Jul 14, 2004
    #9
  10. JKop wrote:
    >
    > Have the C++ dudes considered "allowing" the following?:
    >
    > class Year : public int
    > {
    > // Hijack the constructor and all the = operators, += -= *=
    > /= etc.
    >
    > }
    >


    Sorry. That's not allowed :)

    --
    Karl Heinz Buchegger
    Karl Heinz Buchegger, Jul 14, 2004
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?RWQ=?=

    file restriction - Forms authentication

    =?Utf-8?B?RWQ=?=, May 31, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    358
    Jim Cheshire [MSFT]
    Jun 1, 2004
  2. =?Utf-8?B?Q2hyaXN0aWFuIE51bmNpYXRv?=

    Scripted Window Restriction?

    =?Utf-8?B?Q2hyaXN0aWFuIE51bmNpYXRv?=, Oct 5, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    390
    =?Utf-8?B?Q2hyaXN0aWFuIE51bmNpYXRv?=
    Oct 5, 2004
  3. z f
    Replies:
    2
    Views:
    5,050
  4. Manglu
    Replies:
    1
    Views:
    964
    Anders =?iso-8859-1?Q?Engstr=F6m?=
    Aug 8, 2003
  5. PeteOlcott
    Replies:
    1
    Views:
    934
    Mukul Gandhi
    Feb 5, 2009
Loading...

Share This Page