my first template

Discussion in 'C++' started by Bart Blommerde, Aug 18, 2004.

  1. Compiling the code below results in the following g++ error :

    ' cannot declare member function
    sourceA::DataBuffer<KeyType,ValType>::buffer' within `SourceA' '

    What I'm trying to do here is defining a template for databuffers
    containing elements of any given DataSource. DataSource is a template
    for any database or fileStream containing keys and values. SourceA and
    SourceB are example specializations for this template (though literal
    values are used instead of file or database output).

    It must be something very trivial that I'm doing wrong. Anyone can tell
    me what it is?


    ******************** NONROBUST TESTING CODE **************************

    #include <map>
    #include <hash_map>
    #include <string>

    template<class KeyType, class ValType> class DataBuffer
    {
    private :
    hash_map<KeyType, ValType> buf;

    public :
    DataBuffer(){}
    ~DataBuffer(){}

    void buffer(DataSource<KeyType, ValType> &ds,
    const KeyType &lower, const KeyType &upper);
    ValType * getElement(const KeyType &id);
    };


    template<class KeyType, class ValType> void DataBuffer<KeyType,
    ValType>::buffer(DataSource<KeyType, ValType> &ds,
    KeyType &lower, KeyType &upper)
    {
    ds.store(lower, upper, buf);
    }


    template<class KeyType, class ValType> ValType *
    DataBuffer<KeyType, ValType>::getElement(KeyType &id)
    {
    return &(buf[id]);
    }


    template<class KeyType, class ValType> class DataSource
    {
    public :
    DataSource();
    virtual ~DataSource();

    virtual void store(const KeyType &lower,
    const KeyType &upper,
    hash_map<KeyType, ValType> &data);
    };


    class SourceA : public DataSource<int, int>
    {
    private :
    vector<int> v;

    public :
    SourceA(){
    {
    v.resize(3);
    v[0] = 2;
    v[1] = -1;
    v[2] = 14;
    }
    ~SourceA(){}

    void store(const int lower, const int upper,
    hash_map<int, int>)
    {
    for (int i=lower; i <= upper; i++)
    {

    {
    data = v;
    }
    }
    };


    class SourceB : public DataSource<string, int>
    {
    private :
    map<string, int> m;

    public :
    SourceB()
    {
    m["aa"] = 1;
    m["cc"] = 3;
    m["cd"] = 5;
    }
    ~SourceB(){}

    void store(const string &lower, const string &upper,
    hash_map<string, int> &data)
    {
    map<string, int>::iterator cur = m.begin();
    map<string, int>::iterator end = m.end();
    while (cur != end && *cur <= upper)
    {
    if (*cur >= lower)
    {
    data[cur->first] = cur->second;
    ++cur;
    }
    }
    }
    };
     
    Bart Blommerde, Aug 18, 2004
    #1
    1. Advertising

  2. Re: my first template (readable)

    Compiling the code below results in the following g++ error :

    ' cannot declare member function
    sourceA::DataBuffer<KeyType,ValType>::buffer' within `SourceA' '

    What I'm trying to do here is defining a template for databuffers
    containing elements of any given DataSource. DataSource is a template
    for any database or fileStream containing keys and values. SourceA and
    SourceB are example specializations for this template (though literal
    values are used instead of file or database output).

    It must be something very trivial that I'm doing wrong. Anyone can tell
    me what it is?


    ******************** NONROBUST TESTING CODE **************************

    #include <map>
    #include <hash_map>
    #include <string>

    template<class KeyType, class ValType> class DataBuffer
    {
    private :
    hash_map<KeyType, ValType> buf;

    public :
    DataBuffer(){}
    ~DataBuffer(){}

    void buffer(DataSource<KeyType, ValType> &ds,
    const KeyType &lower, const KeyType &upper);
    ValType * getElement(const KeyType &id);
    };


    template<class KeyType, class ValType> void DataBuffer<KeyType,
    ValType>::buffer(DataSource<KeyType, ValType> &ds,
    KeyType &lower, KeyType &upper)
    {
    ds.store(lower, upper, buf);
    }


    template<class KeyType, class ValType> ValType *
    DataBuffer<KeyType, ValType>::getElement(KeyType &id)
    {
    return &(buf[id]);
    }


    template<class KeyType, class ValType> class DataSource
    {
    public :
    DataSource();
    virtual ~DataSource();

    virtual void store(const KeyType &lower,
    const KeyType &upper,
    hash_map<KeyType, ValType> &data);
    };


    class SourceA : public DataSource<int, int>
    {
    private :
    vector<int> v;

    public :
    SourceA(){
    {
    v.resize(3);
    v[0] = 2;
    v[1] = -1;
    v[2] = 14;
    }
    ~SourceA(){}

    void store(const int lower, const int upper,
    hash_map<int, int>)
    {
    for (int i=lower; i <= upper; i++)
    {

    {
    data = v;
    }
    }
    };


    class SourceB : public DataSource<string, int>
    {
    private :
    map<string, int> m;

    public :
    SourceB()
    {
    m["aa"] = 1;
    m["cc"] = 3;
    m["cd"] = 5;
    }
    ~SourceB(){}

    void store(const string &lower, const string &upper,
    hash_map<string, int> &data)
    {
    map<string, int>::iterator cur = m.begin();
    map<string, int>::iterator end = m.end();
    while (cur != end && *cur <= upper)
    {
    if (*cur >= lower)
    {
    data[cur->first] = cur->second;
    ++cur;
    }
    }
    }
    };
     
    Bart Blommerde, Aug 18, 2004
    #2
    1. Advertising

  3. Re: my first template (readable)

    Bart Blommerde wrote:
    > Compiling the code below results in the following g++ error :
    >
    > ' cannot declare member function
    > sourceA::DataBuffer<KeyType,ValType>::buffer' within `SourceA' '
    >
    > What I'm trying to do here is defining a template for databuffers
    > containing elements of any given DataSource. DataSource is a template
    > for any database or fileStream containing keys and values. SourceA and
    > SourceB are example specializations for this template (though literal
    > values are used instead of file or database output).
    >
    > It must be something very trivial that I'm doing wrong. Anyone can tell
    > me what it is?
    >
    >
    > ******************** NONROBUST TESTING CODE **************************
    >
    > #include <map>
    > #include <hash_map>


    There is no such standard header.

    > #include <string>
    >
    > template<class KeyType, class ValType> class DataBuffer
    > {
    > private :
    > hash_map<KeyType, ValType> buf;


    'hash_map' is undefined.

    >
    > public :
    > DataBuffer(){}
    > ~DataBuffer(){}
    >
    > void buffer(DataSource<KeyType, ValType> &ds,


    'DataSource' is undefined [here].

    > const KeyType &lower, const KeyType &upper);
    > ValType * getElement(const KeyType &id);
    > };
    > [...the rest of the non-compilable source snipped...]


    Perhaps if you post the complete compilable (except for the error you're
    asking about) piece of code, we could help you. The code you posted is
    full of syntax and semantic errors. Did you just type it in? Don't.
    Copy it from your source and paste into the posting.

    Victor
     
    Victor Bazarov, Aug 18, 2004
    #3
  4. Re: my first template (readable)

    >> #include <hash_map>
    >
    >
    > There is no such standard header.


    Say what?

    http://www.sgi.com/tech/stl/hash_map.html

    > Perhaps if you post the complete compilable (except for the error you're
    > asking about) piece of code, we could help you. The code you posted is
    > full of syntax and semantic errors. Did you just type it in? Don't.
    > Copy it from your source and paste into the posting.


    The code is copied from different source files. Excuse me for mixing up
    the order of declarations, but the code is just meant as an example of
    incorrect template usage. The problem can better be identified by
    looking at the template definitions than by compiling the code.


    Bart
     
    Bart Blommerde, Aug 18, 2004
    #4
  5. Bart Blommerde

    Pete Guest

    Re: my first template (readable)

    Bart Blommerde wrote:

    >>> #include <hash_map>

    >>
    >>
    >> There is no such standard header.

    >
    > Say what?
    >
    > http://www.sgi.com/tech/stl/hash_map.html


    From http://www.sgi.com/tech/stl/FAQ.html :

    Are hash tables part of the C++ standard?
    No. The hash table classes (hash_set, hash_map hash_multiset hash_multimap
    hash) are an extension. They may be added to a future revision of the C++
    standard.

    The rope and slist classes are also extensions.
     
    Pete, Aug 18, 2004
    #5
  6. Re: my first template (Compilable)

    The code below can be compiled by g++ 2.95 (and probably g++ 3.x),
    except of course for the before mentioned error.


    ******************* NONROBUST TESTING CODE ***************


    #include <map>
    #include <hash_map>
    #include <string>

    using namespace std;

    template<class KeyType, class ValType> class DataSource
    {
    public :
    DataSource();
    virtual ~DataSource();

    virtual void store(const KeyType &lower,
    const KeyType &upper,
    hash_map<KeyType, ValType> &data);
    };


    class SourceA : public DataSource<int, int>
    {
    private :
    vector<int> v;

    public :
    SourceA()
    {
    v.resize(3);
    v[0] = 2;
    v[1] = -1;
    v[2] = 14;
    }
    ~SourceA(){}

    void store(const int lower, const int upper,
    hash_map<int, int>)
    {
    for (int i=lower; i <= upper; i++)
    {

    {
    data = v;
    }
    }
    };


    class SourceB : public DataSource<string, int>
    {
    private :
    map<string, int> m;

    public :
    SourceB()
    {
    m["aa"] = 1;
    m["cc"] = 3;
    m["cd"] = 5;
    }
    ~SourceB(){}

    void store(const string &lower, const string &upper,
    hash_map<string, int> &data)
    {
    map<string, int>::iterator cur = m.begin();
    map<string, int>::iterator end = m.end();
    while (cur != end && *cur <= upper)
    {
    if (*cur >= lower)
    {
    data[cur->first] = cur->second;
    ++cur;
    }
    }
    }
    };


    template<class KeyType, class ValType> class DataBuffer
    {
    private :
    hash_map<KeyType, ValType> buf;

    public :
    DataBuffer(){}
    ~DataBuffer(){}

    void buffer(DataSource<KeyType, ValType> &ds,
    const KeyType &lower, const KeyType &upper);
    ValType * getElement(const KeyType &id);
    };


    template<class KeyType, class ValType> void DataBuffer<KeyType,
    ValType>::buffer(DataSource<KeyType, ValType> &ds,
    KeyType &lower, KeyType &upper)
    {
    ds.store(lower, upper, buf);
    }


    template<class KeyType, class ValType> ValType *
    DataBuffer<KeyType, ValType>::getElement(KeyType &id)
    {
    return &(buf[id]);
    }
     
    Bart Blommerde, Aug 18, 2004
    #6
  7. Re: my first template (readable)


    > Are hash tables part of the C++ standard?
    > No.


    Okay, wasn't aware of that.

    A bit confusing though, since Stroustrup (The C++ programming language,
    3rd edition) mentions the hash_map in his overview of standard
    containers.




    Bart
     
    Bart Blommerde, Aug 18, 2004
    #7
  8. Re: my first template (Compilable)

    Bart Blommerde wrote:
    > The code below can be compiled by g++ 2.95 (and probably g++ 3.x),


    'probably'? So, you haven't tried, have you?

    > except of course for the before mentioned error.


    No it doesn't. There is a curly brace missing, and at least three other
    mistakes. See below.

    >
    >
    > ******************* NONROBUST TESTING CODE ***************
    >
    >
    > #include <map>
    > #include <hash_map>
    > #include <string>
    >
    > using namespace std;
    >
    > template<class KeyType, class ValType> class DataSource
    > {
    > public :
    > DataSource();
    > virtual ~DataSource();
    >
    > virtual void store(const KeyType &lower,
    > const KeyType &upper,
    > hash_map<KeyType, ValType> &data);
    > };
    >
    >
    > class SourceA : public DataSource<int, int>
    > {
    > private :
    > vector<int> v;
    >
    > public :
    > SourceA()
    > {
    > v.resize(3);
    > v[0] = 2;
    > v[1] = -1;
    > v[2] = 14;
    > }
    > ~SourceA(){}
    >
    > void store(const int lower, const int upper,
    > hash_map<int, int>)
    > {
    > for (int i=lower; i <= upper; i++)
    > {
    >
    > {


    Do you see the two curly braces above this line? Remove one of them.

    > data = v;


    As soon as you get your curly braces in order, 'data' is _undefined_ here.
    Did you mean to name your 'hash_map' argument that?

    > }
    > }
    > };
    >
    >
    > class SourceB : public DataSource<string, int>
    > {
    > private :
    > map<string, int> m;
    >
    > public :
    > SourceB()
    > {
    > m["aa"] = 1;
    > m["cc"] = 3;
    > m["cd"] = 5;
    > }
    > ~SourceB(){}
    >
    > void store(const string &lower, const string &upper,
    > hash_map<string, int> &data)
    > {
    > map<string, int>::iterator cur = m.begin();
    > map<string, int>::iterator end = m.end();
    > while (cur != end && *cur <= upper)


    The line above doesn't compile. Did you mean

    while (cur != end && (*cur).first <= upper)

    > {
    > if (*cur >= lower)


    Same here
    if ((*cur).first >= lower)

    > {
    > data[cur->first] = cur->second;
    > ++cur;
    > }
    > }
    > }
    > };
    >
    >
    > template<class KeyType, class ValType> class DataBuffer
    > {
    > private :
    > hash_map<KeyType, ValType> buf;
    >
    > public :
    > DataBuffer(){}
    > ~DataBuffer(){}
    >
    > void buffer(DataSource<KeyType, ValType> &ds,
    > const KeyType &lower, const KeyType &upper);\


    Note that 'lower' and 'upper' are _const_ here.

    > ValType * getElement(const KeyType &id);
    > };
    >
    >
    > template<class KeyType, class ValType> void DataBuffer<KeyType,
    > ValType>::buffer(DataSource<KeyType, ValType> &ds,
    > KeyType &lower, KeyType &upper)


    Note that 'lower' and 'upper' are NOT _const_ here. This is not the right
    definition for 'buffer' function.

    > {
    > ds.store(lower, upper, buf);
    > }
    >
    >
    > template<class KeyType, class ValType> ValType *
    > DataBuffer<KeyType, ValType>::getElement(KeyType &id)
    > {
    > return &(buf[id]);
    > }
    >


    I really you shouldn't over-use the newsgroup as your code clean-up tool.

    Victor
     
    Victor Bazarov, Aug 18, 2004
    #8
  9. Re: my first template (Compilable)


    > No it doesn't. There is a curly brace missing, and at least three other
    > mistakes. See below.


    Yur right. Sorry for wasting your time. The reported error was just an
    obscure way of g++ telling me I had some syntax errors.

    TOPIC CLOSED!!



    regards,
    Bart
     
    Bart Blommerde, Aug 18, 2004
    #9
    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. Chris Theis
    Replies:
    2
    Views:
    477
    Chris Theis
    Jul 24, 2003
  2. tom_usenet
    Replies:
    0
    Views:
    538
    tom_usenet
    Jul 24, 2003
  3. Replies:
    1
    Views:
    2,113
    Gianni Mariani
    Jun 8, 2007
  4. Stuart Redmann
    Replies:
    5
    Views:
    481
    Stuart Redmann
    Dec 14, 2007
  5. Peng Yu
    Replies:
    3
    Views:
    781
    Thomas J. Gritzan
    Oct 26, 2008
Loading...

Share This Page