Search code examples
c++templatesboostcompiler-errorsshared-ptr

Why is it that defining boost::shared_ptr of a templated behaves differently than boost::shared_ptr of a non templated class


I was trying to integrate the boost::share_ptr into a pair of templated classes that were originally derived from a boost::asio example I found. When I define a type within one class which is a shared::ptr of that class. I can't seem to reference the type in another templated class. If I remove templates from the code, it all compiles.

This won't compile:

#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

using namespace std;

template <typename TSomething1>
class SomeTemplateT : public boost::enable_shared_from_this<SomeTemplateT<TSomething1> >
{
public:
    typedef boost::shared_ptr<SomeTemplateT<TSomething1> > Ptr;

    static Ptr Create()
    {
        return Ptr(new SomeTemplateT<TSomething1>());
    }

    SomeTemplateT()
    {
        cout << "SomeTemplateT created" << endl;
    }
};

template <typename TSomething>
class OtherTemplateT
{
public:
    OtherTemplateT()
    {
        // COMPILATION ERROR HERE
        SomeTemplateT<TSomething>::Ptr someTemplate = SomeTemplateT<TSomething>::Create(); 
    }

private:

};

The code above yields the following compilation error:

src\Templates\main.cpp: In constructor 'OtherTemplateT<TSomething>::OtherTemplateT()':
src\comps\oamp\src\Templates\main.cpp:30: error: expected ';' before 'someTemplate'

Taking virtually the same code without templates compiles without difficulty:

class SomeTemplateT : public boost::enable_shared_from_this<SomeTemplateT>
{
public:
    typedef boost::shared_ptr<SomeTemplateT> Ptr;

    static Ptr Create()
    {
        return Ptr(new SomeTemplateT());
    }

    SomeTemplateT()
    {
        cout << "SomeTemplateT created" << endl;
    }
};

class OtherTemplateT
{
public:
    OtherTemplateT()
    {
        SomeTemplateT::Ptr someTemplate = SomeTemplateT::Create();
    }

private:

};

Platform information: I'm using gcc4.4.0 from MinGW on windows XP (Code:Blocks IDE).

Am I doing something wrong?

EDIT: I forgot to mention that if I replace the use of the Ptr typedef with the full declaration of the shared ptr: boost::shared_ptr Everything compiles fine.

Also, I can use the type in code outside the of the template.


Solution

  • SomeTemplateT<TSomething>::Ptr is a dependent name; that is, its definition depends on the template parameter. The compiler can't assume that it's a type name unless you say so:

    typename SomeTemplateT<TSomething>::Ptr someTemplate = SomeTemplateT<TSomething>::Create();
    ^^^^^^^^