(Syntax - template) a list class that holds objects of another class

Hello,

I have a question about syntax regarding to template of class.
A List in my program is a base class that can hold integers. My teacher told us that this class can also contain objects of another class, which may be a derived class of the class List, using template.

My code for the class List starts like this...

1
2
3
4
5
6
template <typename T>
class List{
...
}

//and its derived class Pets 


In the code above, template T used to be integer, so the List was able to contain a bunch of integers.
Can someone please teach me about syntax for including Pets objects instead of integers in the class List using template?
I also want to make a function that can add one Pet object at a time to the List.

 
void addPets(unknown parameter) // He suggests that we have to use template here, but I don't know what should be parameter(s) of this function and its corresponding syntax. 


Thank you for your time.
Last edited on
1
2
3
4
5
6
7
8
template <typename T>
class List{
//...
   void add(const T &value);
};

List< Pets > a_list_of_pets;
a_list_of_pets.add( Pets(/*params*/) );
If you have not yet encountered rvalue-references, move semantics and perfect forwarding:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <list>

struct pet
{
    pet( const std::string& its_name ) : name(its_name) {}
    pet( const std::string& its_name, const std::string& its_colour ) : name(its_name), colour(its_colour) {}

    std::string name ;
    std::string colour = "unspecified colour" ;
};

// My teacher told us that this class can also contain objects of another class,
// which may be a derived class of the class List, using template.
struct pet_list : std::list<pet> // substitute your home-grown list class for std::list
{
    using std::list<pet>::list ;

    // void addPets(unknown parameter) // He suggests that we have to use template here
    template < typename... ARGS > void add_pet( const ARGS&... args )
    { std::list<pet>::push_back( pet(args...) ) ; }
};

int main ()
{
    pet_list my_pets ;

    my_pets.add_pet( "Fido", "charcoal" ) ;
    my_pets.add_pet( "Felix" ) ;
    my_pets.add_pet( "Mina", "green" ) ;

    for( const pet& p : my_pets ) std::cout << p.name << " (" << p.colour << ")\n" ;
}

http://coliru.stacked-crooked.com/a/71fa3f5d7fa5c1e1


If you have been introduced to rvalue-references, move semantics and perfect forwarding:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <list>

struct pet
{
    pet( std::string its_name ) : name( std::move(its_name) ) {}
    pet( std::string its_name, std::string its_colour )
        : name( std::move(its_name) ), colour( std::move(its_colour) ) {}

    std::string name ;
    std::string colour = "unspecified colour" ;
};

// My teacher told us that this class can also contain objects of another class,
// which may be a derived class of the class List, using template.
struct pet_list : std::list<pet> // substitute your home-grown list class for std::list
{
    using std::list<pet>::list ;

    // void addPets(unknown parameter) // He suggests that we have to use template here
    template < typename... ARGS > void add_pet( ARGS&&... args )
    { std::list<pet>::emplace_back( std::forward<ARGS>(args)... ) ; }
};

int main ()
{
    pet_list my_pets ;

    my_pets.add_pet( "Fido", "charcoal" ) ;
    my_pets.add_pet( "Felix" ) ;
    my_pets.add_pet( "Mina", "green" ) ;

    for( const pet& p : my_pets ) std::cout << p.name << " (" << p.colour << ")\n" ;
}

http://coliru.stacked-crooked.com/a/90bcc896a848c16a
Topic archived. No new replies allowed.