Thread: Initializing contained template objects

  1. #1
    Registered User
    Join Date
    Mar 2016
    Posts
    67

    Initializing contained template objects

    Wine class has a string class object member for label and a template Pair class object member that holds vintage years and numbers of bottles. The Pair class is described as below:

    Code:
    #include <iostream>
    #include <string>
    template <class T1, class T2>
    class Pair{
        private:
            T1 a;
            T2 b;
        public:
            T1 & first(); // allows reset of stored values by virtue of returning references;
            T2 & second(); // allows reset of stored values by virtue of returning references;
            T1 first() const { return a; } // report the stored values; 
            T2 second() const { return b; } // report the stored values; 
            Pair(const T1 & aval, const T2 & bval) : a(aval), b(bval) { }
            Pair() {}
    };
    template<class T1, class T2>
    T1 & Pair<T1,T2>::first(){
    return a;
    }
    template<class T1, class T2>
    T2 & Pair<T1,T2>::second(){
    return b;
    }
    The Wine class declaration starts off as follows before I run into trouble:

    Code:
    #include<iostream>
    #include<valarray>
    #include<string>
    #include<Pair.h>
    
    
    using namespace std;
    class Wine{
        private:
            typedef valarray<int>ArrayInt;
            typedef Pair<ArrayInt,ArrayInt>PairArray;
            string m_label;
            PairArray m_PA; 
            int m_years; 
        public:
            Wine();
            Wine(string l = "No Label", int y = 0):m_label(l), m_years(y){};
            Wine( int yr[],  int bot[]){};
            Wine(const char * l, int y, const int yr[], const int bot[]){    };
    };
    Problem I am having is how to pass int yr[], int bot[] to vintage years and bottles respectively. If it was:
    Code:
    typedef Pair<int, int> PairArray;
    then
    Code:
     Wine (int yr, int bot):m_PA(yr, bot){};
    seemed to work but I can't find a way to pass the int arrays to the template object member. Any suggestions would be most welcome. Thanks
    Last edited by sean_cantab; 05-30-2016 at 08:03 PM.

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    8,953
    I'm assuming, after some thought on this code, that I understand the goal of the Wine type:

    m_label: brand on the bottle
    m_years: total number of years in the PairArray.
    m_PA: the types would be correct, since you can have multiple bottles of the same label in different vintage years.

    If I understand correctly then I don't think you need m_years at all. Simply call size on (one or both of) the valarray:
    Code:
    m_PA.first().size()
    I could be wrong on the purpose of m_years, though.

    Anyway:
    Code:
    Wine::Wine(const char * l, int y, const int yr[], const int bot[], const size_t yr_len, const size_t bot_len)
    : m_label(l) 
    , m_years(y)
    , m_PA( IntArray(yr, yr_len), IntArray(bot, bot_len) ) // assuming that is the order
    {
        // intentionally empty
    }
    Not depending entirely on initialization lists almost seems more sane. I did the most complex constructor. You figure out the rest.
    Last edited by whiteflags; 05-30-2016 at 09:43 PM.

  3. #3
    Registered User
    Join Date
    Mar 2016
    Posts
    67
    Many thanks for your reply.Perhaps m_years can be used, instead of yr_len, bot_len, in the following manner:
    Code:
    Wine(const char * l, int y, const int yr[], const int bot[]):m_label(l), m_years(y), m_PA(ArrayInt(yr, m_years), ArrayInt(bot, m_years)){};
    However what I was trying to do initially, without success, was to pass the arrays as pointer/reference to ArrayInt without specifying size which might come later with dynamic memory allocation. Is there a way to do that as well?

    Many thanks once again for your response.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    8,953
    Perhaps m_years can be used, instead of yr_len, bot_len, in the following manner:
    Why does it sound like you don't know?

    However what I was trying to do initially, without success, was to pass the arrays as pointer/reference to ArrayInt without specifying size which might come later with dynamic memory allocation. Is there a way to do that as well?
    Just saying that you will use dynamic memory allocation doesn't change much. No matter if you call new[], what you are supposed to do is pass the pointer and the size, otherwise the called function has no idea how large the array is.

    There is no getting around the fact that valarray requires a size for its array constructor:
    Code:
    valarray (const T* p, size_t n);
    If you mean replacing int bot[] and int yr[] with valarray<int> objects you pass in to construct Wine, yeah you can do that. It's closer to what I think you want because you wouldn't have to pass in a size variable. But it also means that the type of parameter isn't really an array anymore - it's a valarray<int> (or an initializer_list, maybe, though that is a C++11 feature). You would need to have one constructor for valarray<int> and one constructor for arrays, (and one constructor for initializer lists) if you want the programmer to be able to use their types of choice. They are all equally valid ways to make Wine objects, from what I can tell. The decision ultimately lies with you.

    I would caution you though, valarray<int> doesn't grow on its own like a vector<int> does. You have to explicitly call resize().
    Last edited by whiteflags; 05-31-2016 at 01:03 PM.

  5. #5
    Registered User
    Join Date
    Mar 2016
    Posts
    67
    Thanks, I'll stick to int bot[] and int yr[] in this case. Particularly useful in #2 was this bit:
    Code:
     m_PA.first().size()
    as I had to define a couple of methods later on that required access to the individual valarrays and their elements and I had no idea how to do this without this code. Great help!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 01-06-2015, 08:04 AM
  2. this self contained program
    By a.mlw.walker in forum C Programming
    Replies: 27
    Last Post: 02-09-2013, 03:19 PM
  3. how to see if one string is contained in the other
    By bigal1496 in forum C Programming
    Replies: 1
    Last Post: 08-02-2009, 05:23 PM
  4. Initializing Objects with constructors
    By freddyvorhees in forum C++ Programming
    Replies: 1
    Last Post: 07-24-2008, 07:11 AM
  5. Self contained help
    By loggjam in forum C Programming
    Replies: 4
    Last Post: 08-05-2002, 11:20 AM

Tags for this Thread