0

I am trying to write a simple list for managing smart pointers. You add pointer to a list, when the list is destroyed all the objects pointed are destroyed. Here is a code that works :

#include <iostream>
#include <list>

class Obj
{
public:
   Obj(){std::cout<<"created "<<this<<" \n";}
   ~Obj(){std::cout<<"deleted "<<this<<" \n";}
};

template <class T>
class TList : public std::list<std::shared_ptr<T>>
{
public:
   TList(){}
   ~TList(){
   }
   TList &operator<<(T* t)
   {
      std::shared_ptr<T> p;
      p.reset(t);
      this->push_back(p);
      return *this;
   }
};


int main(int argc, char *argv[])
{
   TList<Obj> list;
   list<<new Obj;
   return 0;
}

But I would like to use a pointer for T in order to declare the list like that :

 TList<Obj*> list;

Here is the code I tried but doesn't work, and error with template are always blurry :

#include <iostream>
#include <list>

class Obj
{
public:
   Obj(){std::cout<<"created "<<this<<" \n";}
   ~Obj(){std::cout<<"deleted "<<this<<" \n";}
};

template <class T>
class TList : public std::list<std::shared_ptr<std::remove_pointer<T>::type>>
{
public:
   TList(){}
   ~TList(){
   }
   TList &operator<<(T t)
   {
      std::shared_ptr<std::remove_pointer<T>::type> p;
      p.reset(t);
      this->push_back(p);
      return *this;
   }
};

int main(int argc, char *argv[])
{
   TList<Obj*> list;
   list<<new Obj;
   return 0;
}

Errors :

main.cpp(12): warning C4346: 'std::remove_pointer<_Ty>::type': dependent name is not a type
main.cpp(12): note: prefix with 'typename' to indicate a type
main.cpp(25): note: see reference to class template instantiation 'TList<T>' being compiled
main.cpp(12): error C2923: 'std::shared_ptr': 'std::remove_pointer<_Ty>::type' is not a valid template type argument for parameter '_Ty'
main.cpp(12): note: see declaration of 'std::remove_pointer<_Ty>::type'
main.cpp(12): error C3203: 'shared_ptr': unspecialized class template can't be used as a template argument for template parameter '_Ty', expected a real type
rturrado
  • 7,699
  • 6
  • 42
  • 62
NiHoT
  • 342
  • 5
  • 17
  • 1
    Does this answer your question? [Where and why do I have to put the "template" and "typename" keywords?](https://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords) – Patrick Roberts Nov 18 '22 at 14:04
  • 3
    Please node that the standard containers aren't really designed for public inheritance. You should consider creating your overloaded `<<` operator function as a non-member function (like `template std::list>& operator<<(std::list>&, T&&);` or similar) – Some programmer dude Nov 18 '22 at 14:08
  • 1
    Alternatively, you can use the composition pattern, i.e. encaspulate a `std::list` member in your class and delegate most operations to it. – Serge Ballesta Nov 18 '22 at 16:29
  • 1
    As commented, I would consider using aggregation and not inheritance for `TList`. Also, prefer to use `std::make_shared` instead of `new` when working with smart pointers. [Demo](https://godbolt.org/z/djqrfYEhz) – rturrado Nov 18 '22 at 16:30
  • 1
    instead of `std::remove_pointer::type` put `std::remove_pointer_t` – QuentinUK Nov 18 '22 at 17:16

0 Answers0