Thread: Quick question about types...

  1. #1
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654

    Quick question about types...

    Just a quick question about what would be (probably) the best way to solve this.

    I have 3 arrays. They are all of the same type, but have different dimensions:
    Code:
    typedef bounds_array<int, 3, 1> PointsArrayEasy;
    typedef bounds_array<int, 5, 1> PointsArrayNormal;
    typedef bounds_array<int, 7, 1> PointsArrayHard;
    And I have a simple function that returns a reference to the proper array depending on the "difficulty level":
    Code:
    PointsArray& GetReqPointsForLevelArray(Difficulty_e Difficulty)
    {
    	switch (Difficulty)
    	{
    		case Easy: return g_ReqPointsForLevel_Easy;
    		case Normal: return g_ReqPointsForLevel_Normal;
    		case Hard: return g_ReqPointsForLevel_Hard;
    		default: assert(!"Invalid difficulty!"); return g_ReqPointsForLevel_Easy;
    	}
    }
    Of course this will not work. Which type should I choose to return, since they are all considered different?
    What would be a good way of solving such a problem?

    Since Difficulty is a run-time parameter, I am guessing the correct type can only be deduced at runtime.
    But then the question becomes on how to do that in a way that doesn't look like a C mess?
    Last edited by Elysia; 12-05-2008 at 05:41 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    What is this bounds_array stuff, and do the numeric parameters have to be template arguments?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Wouldn't it be simpler to not have the size fixed to the type, i.e., to just use an ordinary vector? Or, you use a dynamic array whose size cannot change once it is created.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by anon View Post
    What is this bounds_array stuff, and do the numeric parameters have to be template arguments?
    Forgot about that one.
    It's a simply wrapper that enforces bounds. So, an array can start at 1 and end at 7. Syntactic sugar, if you will. It's a nice feature of VB(A).
    Code:
    template<typename T, int UpperBound, int LowerBound = 0> class bounds_array
    {
    	boost::array<T, UpperBound - LowerBound + 1> m_Array;
    public:
    	const T& operator [] (int Index) const
    	{
    		return GetIndex(Index);
    	}
    	T& operator [] (int Index)
    	{
    		const T& temp = GetIndex(Index);
    		return const_cast<T&>(temp);
    	}
    private:
    	const T& GetIndex(int Index) const
    	{
    		assert(Index >= LowerBound);
    		assert(Index <= UpperBound);
    		return m_Array[Index - LowerBound];
    	}
    };
    Quote Originally Posted by laserlight View Post
    Wouldn't it be simpler to not have the size fixed to the type, i.e., to just use an ordinary vector? Or, you use a dynamic array whose size cannot change once it is created.
    Perhaps. I'm just thinking of the fact that depending on the "difficulty", a different number of elements will be populated. And I wanted to, if possible, to keep the whole "bounds" concept, but I think I may toss it away if necessary.

    I think a vector might work, but... I wonder if it's possible to keep the bounds intact, as well? Only problem might be that those bounds would be checked at runtime and not compile time...

    Perhaps I would need a runtime bounds array instead of a compile time one...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The bounds are checked at runtime anyway; that's what assert does. The only difference is that both operands are runtime values, instead of one being a compile-time value. Unless this value is 0, though, I don't see how that helps generating faster code. Not to mention that the check is there in debug mode only anyway, so faster code doesn't even matter.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    So you do agree then, that the bounds should be moved from compile time to runtime and problem solved? It doesn't change much, after all.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Which type should I choose to return, since they are all considered different?
    If you selectively return all three, which would you store?

    So you do agree then, that the bounds should be moved from compile time to runtime and problem solved?
    Or you could leave it a compile time value and employee polymorphism.

    Soma

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by phantomotap View Post
    If you selectively return all three, which would you store?
    That is further a problem - I must be able to deduce the type on both ends.

    Or you could leave it a compile time value and employee polymorphism.
    Unfortunately, I have no idea how to achieve that.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Unfortunately, I have no idea how to achieve that.
    It depends on what you want to do, when you want to do it, and when you can do it.

    I suggest this sort of thing in real life because it has the added benefit of supporting compile-time and run-time polymorphism without otherwise affecting the types involved.

    They key here is that, without the relevant marker being set, 'bounded_array' has no virtual methods, nor will it participate in resolution related to inheritance.

    Soma

    Code:
    template
    <
      typename type_F
    >
    struct bounded_array_interface
    {
      //...
      virtual T & operator []
      (
        size_t index_f
      ) = 0;
      virtual size_t get_lower_bounds() = 0;
      virtual size_t get_upper_bounds() = 0;
      //...
    };
    
    template
    <
      typename type_F,
      size_t upper_F,
      size_t lower_F,
      typename inherit_F = false
    >
    struct bounded_array: public do_inherit<inherit_F, bounded_array_interface>::type
    {
      //...
      T & operator []
      (
        size_t index_f
      )
      {
        //...
      }
      size_t get_lower_bounds()
      {
        //...
      }
      size_t get_upper_bounds()
      {
        //...
      }
      //...
    };

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I see! I have used a similar approach before.
    But it will incur a small performance cost due to the virtual functions, aside from the additional code.
    I'm going with the easier approach - to move the compile-time bounds to runtime bounds for now.

    EDIT:
    But I see that will, of course, require an embedded vector instead of an embedded array, which might add an overhead, as well.
    I'll choose the vector route for now and test the other approach if I get performance problems.
    Last edited by Elysia; 12-05-2008 at 07:39 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    The larch
    Join Date
    May 2006
    Posts
    3,573
    But I see that will, of course, require an embedded vector instead of an embedded array, which might add an overhead, as well.
    Why?

    In any case, perhaps you just need a bounds_vector in addition to bounds_array? After all array covers just a part of the usage needs. (Or perhaps the bounds_x thing could be templated for container type?)
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by anon View Post
    Why?
    Well...
    Code:
    template<typename T> class bounds_vector
    {
    public:
    	bounds_vector(int UpperBound, int LowerBound = 0): m_Array(UpperBound - LowerBound + 1), m_UpperBound(UpperBound), m_LowerBound(LowerBound) { }
    	const T& operator [] (int Index) const
    	{
    		return GetIndex(Index);
    	}
    	T& operator [] (int Index)
    	{
    		const T& temp = GetIndex(Index);
    		return const_cast<T&>(temp);
    	}
    	int GetLowerBound() const { return m_LowerBound; }
    	int GetUppGetLowerBound() const { return m_UpperBound; }
    
    private:
    	const T& GetIndex(int Index) const
    	{
    		assert(Index >= m_LowerBound);
    		assert(Index <= m_UpperBound);
    		return m_Array[Index - m_LowerBound];
    	}
    
    	std::vector<T> m_Array;
    	int m_UpperBound;
    	int m_LowerBound;
    };
    [/quote]
    It adds overhead for a call to vector to prepare dynamic memory (stack is plenty faster, after all), and it has to store its dimensions somewhere.
    So, yes, it definitely has overhead compared to just an array.

    Well, not that it's a terrible overhead, but still. I want it as fast as possible.

    In any case, perhaps you just need a bounds_vector in addition to bounds_array? After all array covers just a part of the usage needs. (Or perhaps the bounds_x thing could be templated for container type?)
    Oh yes, good idea. I will rename it bounds_vector.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I think the possibility was that you can have a non-templated base_bounds_array:

    Code:
    base_bounds_array<int>* arr = new bounds_array<int, 7, 1>;
    However, yes you won't get away with dynamic memory allocations.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yeah, let's keep it simple. No use complaining over spilled milk.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    I... obviously missed something.

    I'm glad you two seem to know what's going on. ^_^;

    Soma

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. very quick question.
    By Unregistered in forum C++ Programming
    Replies: 7
    Last Post: 07-24-2002, 03:48 AM
  2. quick question
    By Unregistered in forum C++ Programming
    Replies: 5
    Last Post: 07-22-2002, 04:44 AM
  3. Quick Question Regarding Pointers
    By charash in forum C++ Programming
    Replies: 4
    Last Post: 05-04-2002, 11:04 AM
  4. Quick Question Regarding Variable Types
    By Drek in forum C++ Programming
    Replies: 2
    Last Post: 01-24-2002, 01:16 PM
  5. Quick question: exit();
    By Cheeze-It in forum C Programming
    Replies: 6
    Last Post: 08-15-2001, 05:46 PM