I'm investigating a problem here when using boost::intrusive::list with templates but to get me started I wrote this small app (which works):-

Code:
#include <boost/intrusive/list.hpp>
#include <string>
#include <iostream>

using namespace std;

struct animal : public boost::intrusive::list_base_hook<>
{
    string name;
    int legs;
    animal (string n, int l) : name{move(n)}, legs{l} {}
};

typedef boost::intrusive::list<animal> animal_list;

void print_list (animal_list &ani)
{
    for (const animal &a : ani)
        cout << " A " << a.name << " has " << a.legs << " legs" << endl;
}

int main()
{
    animal a1{"dog", 4};
    animal a2{"spider", 6};
    animal a3{"budgie", 2};
 
    animal_list animals;

    animals.push_back(a1);
    animals.push_back(a2);
    animals.push_back(a3);

    print_list (animals);

    return 0;
}
Let's suppose I wanted to print out something else with legs - e.g. furniture. This sounds like the kinda thing templates are useful for. So how would I modify the code? e.g

Code:
struct furniture : public boost::intrusive::list_base_hook<>
{
    string name;
    int legs;
    furniture (string n, int l) : name{move(n)}, legs{l} {}
};

typedef boost::intrusive::list<furniture> furniture_list;

void print_list (animal_list &ani)  // <--- Using templates, how would I modify this to accept either furnitures or animals ??
{
    // [[ What would be needed here ?? ]]
}

int main()
{
    animal a1{"dog", 4};
    animal a2{"spider", 6};
    animal a3{"budgie", 2};
 
    animal_list animals;

    animals.push_back(a1);
    animals.push_back(a2);
    animals.push_back(a3);

    furniture f1{"table", 4};
    furniture f2{"chair", 4};

    furniture_list furnitures;

    furnitures.push_back(f1);
    furnitures.push_back(f2);

    print_list ([[ ?? ]]);  // <--- would need to be callable with either furnitures or animals

    return 0;
}