I am trying to implement an own SmartPointer class and after an initial working version I have started to refine the code and now facing an issue, that I am unable to resolve.
Here is the first version:
template<class T>
class SmartPointer
{
private:
T* ptr;
public:
explicit SmartPointer(T* p = nullptr):ptr(p){}
~SmartPointer(){delete(ptr);}
T& operator*(){return *ptr;}
T* operator->(){return ptr;}
};
My problem with this that I have to call it specifying two times that this will be eg. an "int" type of pointer:
SmartPointer<int> intSP(new int());
So I have tried to create a template constructor inside the SmartPointer class's constructor, by changing it to:
template<typename... Args>
explicit SmartPointer(Args... args):ptr(new T(args...)){};
This works fine till the point I provide at least one parameter. But when no parameter is provided the whole class starts not to work at all. (when I have created an instance from it and tried to assign a value, it throw the following error: "assignment of read-only location '* intSP'".
So I have tried to complicate it further, with enable_if on the size of the argument pack, unfortunately with the same results as in the previous case. The enable_if seems not to do anything at all for some reason:
template<typename... Args,
typename = typename std::enable_if<(sizeof...(Args)>0u)>::type>
explicit SmartPointer(Args... args):ptr(new T(args...)){
cout << "constructor with arguments" << endl;
};
template<typename... Args,
typename = typename std::enable_if<(sizeof...(Args)==0u)>::type>
explicit SmartPointer():ptr(new T()){
cout << "constructor without args" << endl;
};
And finally the full code, to have some overview:
#include <iostream>
using namespace std;
#define var2str(var) #var
template<class T>
class SmartPointer
{
private:
T* ptr;
public:
template<typename... Args,
typename = typename std::enable_if<(sizeof...(Args)>0u)>::type>
explicit SmartPointer(Args... args):ptr(new T(args...)){
cout << "constructor with arguments" << endl;
};
template<typename... Args,
typename = typename std::enable_if<(sizeof...(Args)==0u)>::type>
explicit SmartPointer():ptr(new T()){
cout << "constructor without arguments" << endl;
};
~SmartPointer(){delete(ptr);}
T& operator*(){return *ptr;}
T* operator->(){return ptr;}
};
int main(int, char**) {
SmartPointer<int> intSP(5);//new int());
cin>>*intSP;
cout << *intSP << " stored in "<< var2str(intSP) << endl;
}