manually calling a template argument constructor, How ???

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?TmFkYXY=?=

    #1

    manually calling a template argument constructor, How ???

    Hi,

    I am trying to manually call a constructor of a template argument, the
    compiler returns “error C2039: ‘T’ : is not a member...”

    How can I manually call the constructor of a template argument?

    Please note that I cannot use the ‘new’ operator ( as long as it allocates
    memory ), see the following code snnipet as an example of what I am trying to
    do.


    class HEADER {
    LONG lStam;
    HEADER() : lStam(0) {}
    };

    template< typename T >
    class CMyTest
    {
    protected:
    CMyTest();
    ~CMyTest();

    typename T m_pObjects[0];
    public:
    static HRESULT CreateInstance( IN int iObjCount, OUT CMyTest** ppObj) {
    *ppObj = (CMyTest*)mallo c(sizeof(CMyTes t) + sizeof(T) * iObjCount);
    if(0 == *ppObj)
    return E_OUTOFMEMORY;
    (*ppObj)->CMyTest::CMyTe st();// Works, calls the constructor
    for(int i = 0; i < iObjCount; i++)
    (*ppObj)->m_pObjects[0].T::T();// error C2039: 'T' : is not a member of
    'HEADER'
    }
    };

    int _tmain(int argc, _TCHAR* argv[])
    {
    CMyTest<HEADER> * pTest;
    CMyTest<HEADER> ::CreateInstanc e(10, &pTest);
    }

    The above code doesn’t have any practical meaning, it’s only goal is to
    demonstrate the problem I am describing here

    --
    Nadav

  • Carl Daniel [VC++ MVP]

    #2
    Re: manually calling a template argument constructor, How ???

    Nadav wrote:
    Hi,
    >
    I am trying to manually call a constructor of a template argument, the
    compiler returns "error C2039: 'T' : is not a member..."
    >
    How can I manually call the constructor of a template argument?
    >
    Please note that I cannot use the 'new' operator ( as long as it
    allocates memory ), see the following code snnipet as an example of
    what I am trying to do.
    (*ppObj)->CMyTest::CMyTe st();// Works, calls the constructor
    VC++ Extension, not portable C++ code. There's no way to "call a
    constructor" in standard C++.
    for(int i = 0; i < iObjCount; i++)
    (*ppObj)->m_pObjects[0].T::T();// error C2039: 'T' : is not a
    member of 'HEADER'
    Here the extension fails.
    The above code doesn't have any practical meaning, it's only goal is
    to demonstrate the problem I am describing here
    The correct way to do this is to use "placement new":

    #include <new>

    // (*ppObj)->CMyTest::CMyTe st(); // Non-standard VC++ extension

    new (*ppObj) CMyTest(); // standard, placement-new solution

    // (*ppObj)->m_pObjects[0].T::T(); // extension breaks down

    new (*ppObj) T(); // standard, placement-new solution

    -cd


    Comment

    • Ben Voigt [C++ MVP]

      #3
      Re: manually calling a template argument constructor, How ???


      "Carl Daniel [VC++ MVP]" <cpdaniel_remov e_this_and_nosp am@mvps.org.nos pam>
      wrote in message news:%23vp2Wo%2 3mIHA.3636@TK2M SFTNGP02.phx.gb l...
      Nadav wrote:
      >Hi,
      >>
      >I am trying to manually call a constructor of a template argument, the
      >compiler returns "error C2039: 'T' : is not a member..."
      >>
      >How can I manually call the constructor of a template argument?
      >>
      >Please note that I cannot use the 'new' operator ( as long as it
      >allocates memory ), see the following code snnipet as an example of
      >what I am trying to do.
      > (*ppObj)->CMyTest::CMyTe st();// Works, calls the constructor
      >
      VC++ Extension, not portable C++ code. There's no way to "call a
      constructor" in standard C++.
      >
      > for(int i = 0; i < iObjCount; i++)
      > (*ppObj)->m_pObjects[0].T::T();// error C2039: 'T' : is not a
      >member of 'HEADER'
      >
      Here the extension fails.
      I think I once found that using a typedef solves the problem as well (and
      solves the problem of how to invoke the destructor as well, so even if you
      construct with placement new you may still need the trick.

      typedef typename T TValue;
      TValue* pT = (TValue*)malloc (sizeof(TValue) );
      pT->TValue(); or pT->TValue::TValue ();
      ....
      pT->~TValue(); or pT->TValue::~TValu e();
      >
      >The above code doesn't have any practical meaning, it's only goal is
      >to demonstrate the problem I am describing here
      >
      The correct way to do this is to use "placement new":
      >
      #include <new>
      >
      // (*ppObj)->CMyTest::CMyTe st(); // Non-standard VC++ extension
      >
      new (*ppObj) CMyTest(); // standard, placement-new solution
      >
      // (*ppObj)->m_pObjects[0].T::T(); // extension breaks down
      >
      new (*ppObj) T(); // standard, placement-new solution
      >
      -cd
      >
      >

      Comment

      • Carl Daniel [VC++ MVP]

        #4
        Re: manually calling a template argument constructor, How ???

        Ben Voigt [C++ MVP] wrote:
        I think I once found that using a typedef solves the problem as well
        (and solves the problem of how to invoke the destructor as well, so
        even if you construct with placement new you may still need the trick.
        >
        typedef typename T TValue;
        TValue* pT = (TValue*)malloc (sizeof(TValue) );
        pT->TValue(); or pT->TValue::TValue ();
        ...
        pT->~TValue(); or pT->TValue::~TValu e();
        The difference is, for the destructor

        template<class T...
        T* pt = ...
        pt->~T();

        is required to work by the C++ standard (at least, I'm pretty sure it's
        required to work!), and does work under VC++ 2005 (I didn't try anything
        older). The typedef trick may be required for some older versions - I don't
        have anything older installed to try it out.

        -cd


        Comment

        Working...