1

I am experimenting with Policies and CRTP and came across this issue.
So I am creating a SmartPtr which along with all customisation points also have releasing policy (the rest I will skip for the sake of simplicity)

template<typename T>
class Releaser
{
    int someDummyState;
public:
    Releaser(int st):someDummyState(st) {}
    void release()
    {
        cout << someDummyState << endl;
        static_cast<T*>(this)->data = nullptr;
    }
};

template<typename T, template<typename> typename Rel = Releaser>
class SmartPtr :
    public Rel<SmartPtr<T,Rel>>
{
public:
    SmartPtr(T* d,int val) :
        Rel(val), // This line is error prone, Rel<SmartPtr>(val) solves this
        data(d)
    {}

    T* operator*()
    {
        return data;
    }

private:
    friend class Releaser<SmartPtr>; // We need this as in the releaser we are accessing the private member
    T* data;
};

int main() 
{
    SmartPtr<int> S(new int(3),8); 
    S.release();
}

So this gives me error C2512: 'Releaser<SmartPtr<int,Releaser>>': no appropriate default constructor available

But I don't see how I am invoking a default constructor for the Rel? I believe I am explicitly passing the val to the constructor.
This issue is resolved the I specify the template parameter for Rel (Rel<SmartPtr>(val)).

Can someone please explain why I need to specify the base type template parameter and why it was trying to invoke the default constructor?

digito_evo
  • 3,216
  • 2
  • 14
  • 42
Eduard Rostomyan
  • 7,050
  • 2
  • 37
  • 76
  • *Can someone please explain why I need to specify the base type template parameter and why it was trying to invoke the default constructor?* --Maybe because the syntax is exactly as if you are trying to default construct an object? C++ has various places where you have to help the compiler out to disambiguate certain syntaxes, and this may be one of those situations. – PaulMcKenzie Dec 26 '21 at 22:03
  • @PaulMcKenzie, How does Rel(val), this look like I am trying to default construct when I am passing an integer to the constructor?! – Eduard Rostomyan Dec 26 '21 at 22:04
  • You're not getting my point: [See this](http://coliru.stacked-crooked.com/a/2e2482fce0aaa932). The compiler blindly assumes that `Rel` is a member variable, and you're trying to construct it. – PaulMcKenzie Dec 26 '21 at 22:05
  • @PaulMcKenzie still dont get your point. So the compiler doesnt understand that Rel is related to Rel and thinks its a member + trying to call bases's constructor with no arguments. – Eduard Rostomyan Dec 26 '21 at 22:09
  • 3
    `Rel` is the type. That is not the same as plain-old `Rel`. That's probably why the compiler is not equating the two. – PaulMcKenzie Dec 26 '21 at 22:11

0 Answers0