473,706 Members | 2,064 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Why isn't this template being instantiated?

This code get's a link error (I'm guessing because the template isn't being
instantiated).. .

// For using templates to simplify deleting items
template <class T>
// Returns the next ADHL in the list
AbstractDataHol derList*
// Used to delete this object and the item it points to
AbstractDataHol derList::Delete ThisItem(void)
{
// do stuff to update list (since this item is being removed)

delete (typename T*)m_thisItem;
delete this;

return m_nextADHL;
}

/* ... */ main (/* ... */)
{
/*************** *************** ***********
* We make some items (CString in this case?)
* and add em to the list, then run the program up here
*************** *************** ***********/

// This part is the important thing
while (myADHL != NULL)
myADHL = myADHL->DeleteThisItem <CString>();

return 0;
}

If I change the DeleteThisItem method in the ADHL class to be the
instanciated template for a CString (ie:
"/*...*/::DeleteThisIte m<CString>(void )"), then there isn't a linking error.
But I'm wondering why the compiler doesn't notice that main is calling the
template with a forced type of CString. Shouldn't the call in main force an
instanciation of the template with T = CString? (as a side note... since
there are no parameters, if <CString> is omited in the DeleteThisItem call,
then this code doesn't even compile, because the type cannot be
determined... which is why i'm wondering, when I say that the type is a
CString, why isn't the CString version of the template created?)
Jul 22 '05 #1
8 1450
de*****@hotmail .com wrote:
This code get's a link error (I'm guessing because the template isn't being
instantiated).. .

// For using templates to simplify deleting items
template <class T>
// Returns the next ADHL in the list
AbstractDataHol derList*
// Used to delete this object and the item it points to
AbstractDataHol derList::Delete ThisItem(void)
{
// do stuff to update list (since this item is being removed)

delete (typename T*)m_thisItem;
delete this;

return m_nextADHL;
}

/* ... */ main (/* ... */)
{
/*************** *************** ***********
* We make some items (CString in this case?)
* and add em to the list, then run the program up here
*************** *************** ***********/

// This part is the important thing
while (myADHL != NULL)
myADHL = myADHL->DeleteThisItem <CString>();

return 0;
}

If I change the DeleteThisItem method in the ADHL class to be the
instanciated template for a CString (ie:
"/*...*/::DeleteThisIte m<CString>(void )"), then there isn't a linking error.
But I'm wondering why the compiler doesn't notice that main is calling the
template with a forced type of CString. Shouldn't the call in main force an
instanciation of the template with T = CString? (as a side note... since
there are no parameters, if <CString> is omited in the DeleteThisItem call,
then this code doesn't even compile, because the type cannot be
determined... which is why i'm wondering, when I say that the type is a
CString, why isn't the CString version of the template created?)


The name CString suggests that you're using Visual C++. Is it by any
chance VC++ v6? Then you need a work-around:

template <class T>
// Returns the next ADHL in the list
AbstractDataHol derList*
// Used to delete this object and the item it points to
AbstractDataHol derList::Delete ThisItem(T* = 0)

By introducing the argument of the same type as you're trying to get the
template to use you can trick the compiler into recognising the need to
instantiate the template correctly.

I am not actually sure about this work-around, do check with the VC++
newsgroup: microsoft.publi c.vc.language.

Victor
Jul 22 '05 #2
> The name CString suggests that you're using Visual C++. Is it by any
chance VC++ v6? Then you need a work-around:

template <class T>
// Returns the next ADHL in the list
AbstractDataHol derList*
// Used to delete this object and the item it points to
AbstractDataHol derList::Delete ThisItem(T* = 0)

By introducing the argument of the same type as you're trying to get the
template to use you can trick the compiler into recognising the need to
instantiate the template correctly.

I am not actually sure about this work-around, do check with the VC++
newsgroup: microsoft.publi c.vc.language.

Victor


Thanks for the info... so I guess in gcc, and other compilers this isn't
necessarily an issue? Other compilers figure this stuff out for me? (mines
..NET... so I guess m$ hasn't tried fixing this yet...) I just ended up doing
this:

template < >
// Returns the next ADHL in the list
AbstractDataHol derList*
// Used to delete this object and the CString item it points to
AbstractDataHol derList::Delete ThisItem < CString > (void)

for each type that I need to delete, as an added bonus I add one for "void"
which doesn't delete the item... just incase I find good reason to do
that... Well... if it's a VC++ ... feature ... 0.o then i'll just member
that I'm smart and they... are... well... thier smart too... but... I'm
SMARTER! ;)

Thanks,
Dead RAM
Jul 22 '05 #3
de*****@hotmail .com wrote:
The name CString suggests that you're using Visual C++. Is it by any
chance VC++ v6? Then you need a work-around:

template <class T>
// Returns the next ADHL in the list
AbstractDataHol derList*
// Used to delete this object and the item it points to
AbstractDataHol derList::Delete ThisItem(T* = 0)

By introducing the argument of the same type as you're trying to get the
template to use you can trick the compiler into recognising the need to
instantiate the template correctly.

I am not actually sure about this work-around, do check with the VC++
newsgroup: microsoft.publi c.vc.language.

Victor

Thanks for the info... so I guess in gcc, and other compilers this isn't
necessarily an issue? Other compilers figure this stuff out for me? (mines
.NET... so I guess m$ hasn't tried fixing this yet...) I just ended up doing
this:

template < >
// Returns the next ADHL in the list
AbstractDataHol derList*
// Used to delete this object and the CString item it points to
AbstractDataHol derList::Delete ThisItem < CString > (void)

for each type that I need to delete, as an added bonus I add one for "void"
which doesn't delete the item... just incase I find good reason to do
that... Well... if it's a VC++ ... feature ... 0.o then i'll just member
that I'm smart and they... are... well... thier smart too... but... I'm
SMARTER! ;)


I may have misinterpreted the situation, sorry about that. The .NET (is
that 7.1?) compiler is far more advanced than v6 when the templates are
concerned.

Since you didn't post the complete code, I couldn't verify the error on
any of the compilers available to me here, so I probably fell into
assuming too much. Try this:
----------------------------------
struct CS {}; // my version of "CString"
struct A { // my version of your "AbstractDataHo lderList"
template<class T> A* foo(); // my "DeleteThisItem "
};

template<class T> A* A::foo() { // definition
T t;
return this;
}

int main() {
A a;
A* pa = &a;
pa = pa->foo<CS>();
}
----------------------------------
It compiles (and links) fine with my copy of VC++ v7.1.

Victor
Jul 22 '05 #4
> I may have misinterpreted the situation, sorry about that. The .NET (is
that 7.1?) compiler is far more advanced than v6 when the templates are
concerned.

Since you didn't post the complete code, I couldn't verify the error on
any of the compilers available to me here, so I probably fell into
assuming too much. Try this:
----------------------------------
struct CS {}; // my version of "CString"
struct A { // my version of your "AbstractDataHo lderList"
template<class T> A* foo(); // my "DeleteThisItem "
};

template<class T> A* A::foo() { // definition
T t;
return this;
}

int main() {
A a;
A* pa = &a;
pa = pa->foo<CS>();
}
----------------------------------
It compiles (and links) fine with my copy of VC++ v7.1.

Victor


Thanks for that info... It didn't solve my problem, but it made me
recognize that I was the one with the error... and not the
compiler/linker... (as is always the case... >.<)

I had my template declairation in a header file:

template <class T> ADHL* DelThis();

which was included with all the code that used the class ADHL but the
definition:

template <class T> ADHL* ADHL::DelThis()
{
// Code goes here...
}

was in a separate cpp file... so the compiler never knew about the work the
template was doing until it was too late... Which I'm guessing is a good
type of error to generate (forces people to put templates in headers...
since they are not code in and of themselves).

Thanks for all the help Victor ;) I'd be lost without it 0.o
Jul 22 '05 #5
<de*****@hotmai l.com> wrote...
I may have misinterpreted the situation, sorry about that. The .NET (is
that 7.1?) compiler is far more advanced than v6 when the templates are
concerned.

Since you didn't post the complete code, I couldn't verify the error on
any of the compilers available to me here, so I probably fell into
assuming too much. Try this:
----------------------------------
struct CS {}; // my version of "CString"
struct A { // my version of your "AbstractDataHo lderList"
template<class T> A* foo(); // my "DeleteThisItem "
};

template<class T> A* A::foo() { // definition
T t;
return this;
}

int main() {
A a;
A* pa = &a;
pa = pa->foo<CS>();
}
----------------------------------
It compiles (and links) fine with my copy of VC++ v7.1.

Victor


Thanks for that info... It didn't solve my problem, but it made me
recognize that I was the one with the error... and not the
compiler/linker... (as is always the case... >.<)

I had my template declairation in a header file:

template <class T> ADHL* DelThis();

which was included with all the code that used the class ADHL but the
definition:

template <class T> ADHL* ADHL::DelThis()
{
// Code goes here...
}

was in a separate cpp file... so the compiler never knew about the work
the template was doing until it was too late... Which I'm guessing is a
good type of error to generate (forces people to put templates in
headers... since they are not code in and of themselves).


You could do this special thing in your separate cpp file: add explicit
instantiations. After the definition of the template member add lines
like these:

template ADHL* ADHL::DelThis<C Sting>();
template ADHL* ADHL::DelThis<i nt>();

and so on, for all types you think are relevant. The compiler will have
to generate all the instantiations mentioned. It usually leads to code
bloat, but it does help hide the implementation, besides if your template
is intended to work only with a limited set of types, it's not such a bad
deal.

Victor
Jul 22 '05 #6
de*****@hotmail .com schrieb:
This code get's a link error (I'm guessing because the template isn't being
instantiated).. .

// For using templates to simplify deleting items
template <class T>
// Returns the next ADHL in the list
AbstractDataHol derList*
// Used to delete this object and the item it points to
AbstractDataHol derList::Delete ThisItem(void)
{
// do stuff to update list (since this item is being removed)

delete (typename T*)m_thisItem;
delete this;

return m_nextADHL;


On a side note, the above line looks suspiciously like you're shooting
yourself in the foot there. Assuming m_nextADHL is a member of this,
you must not use it anymore, as this it's no longer valid. To return a
data member's value you need to make a local copy before committing
suicide and then return that copy's value. No more accessing non-static
data members or calling non-static member functions or anything else
that involves the this pointer after self-destruction. Ever.

Regards,
Malte

PS: While such drastic consequences of dereferencing invalid pointers
are unlikely in today's OSs unless you're hacking the kernel, I actually
once killed half of my file system with something like that under DOS...
Jul 22 '05 #7
>
You could do this special thing in your separate cpp file: add explicit
instantiations. After the definition of the template member add lines
like these:

template ADHL* ADHL::DelThis<C Sting>();
template ADHL* ADHL::DelThis<i nt>();

and so on, for all types you think are relevant. The compiler will have
to generate all the instantiations mentioned. It usually leads to code
bloat, but it does help hide the implementation, besides if your template
is intended to work only with a limited set of types, it's not such a bad
deal.

Victor


I like that idea, keeps the code clean enough ;) thanks for the tips ;)
Jul 22 '05 #8

On a side note, the above line looks suspiciously like you're shooting
yourself in the foot there. Assuming m_nextADHL is a member of this, you
must not use it anymore, as this it's no longer valid. To return a data
member's value you need to make a local copy before committing suicide and
then return that copy's value. No more accessing non-static data members
or calling non-static member functions or anything else that involves the
this pointer after self-destruction. Ever.

Regards,
Malte

PS: While such drastic consequences of dereferencing invalid pointers are
unlikely in today's OSs unless you're hacking the kernel, I actually once
killed half of my file system with something like that under DOS...


That was once a error for me, but I fixed that long ago... just showed up in
this code due to lazyness ^.~ What I do is make a local ADHL pointer, then
find out what it should point to (pMyPointer = m_nextItem for example...)
then return the pointer to the next, or previous ADHL... or sometimes NULL.
But thanks for the tip... can never be too safe when it comes to playing
with pointers and delete and such ;)

As a side note... I once blew up a palm pilot screen doing something like
this ;) ok... ok... I only made it go "pop" and only a 4x160 pixel area on
the screen doesn't get drawn... So yah... this stuff is bad to do... thanks
for the reminder ;)
Jul 22 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
2093
by: 胡岳偉(Yueh-Wei Hu) | last post by:
Hi all, I have 2 questions about template function as friends in template classes. I don't know why, and hope someone could help me. ============================================================== Question 1: ============================================================== Compile the following codes, and run it.
0
1694
by: Yueh-Wei Hu | last post by:
Victor Bazarov <v.Abazarov@comAcast.net> wrote in message news: ============================================================== > > Question 1: > > ============================================================== > Your code refuses to compile. In function 'foo<a>' 't' is a pointer to > const. Friendship has nothing to do with it. When I remove the attempt > to change 't->c' in foo<a>, it compiles and runs and displays > > T<a, 3>
7
2477
by: Drew McCormack | last post by:
I have a C++ template class which contains a static variable whose construction registers the class with a map. Something like this: template <typename T> class M { static Registrar<M> registrar; }; The constructor of Registrar does the registering when it is initialized.
3
2731
by: sks | last post by:
Hello all Is the usage of extern keyword valid for telling the compiler to NOT instantiate a template and to link it from an another binary? For example: Suppose module A's binary contains a template class called "myTemplate", for which there is an instantiation for 'int' type. Now suppose a class in module B binary wants to use this template
9
1825
by: Christof Warlich | last post by:
Hi, consider this: template<typename Tclass X { public: void doSomething(T t); }; int main(void) { X<intx;
8
1359
by: Imre | last post by:
Hi I'm looking for a way to make sure that whenever a new instance of a class template A is created, then an instance of class template B is also created, with the same template parameters. Of course, I could do it by referencing B<Tfrom A<T>, but I'd like to do it without modifying A at all. I'm afraid it's not possile with separate translation units, but it might still worth asking.
7
2972
by: alex221 | last post by:
In need to implement a tree structure in which every node has arbitrary number of children the following code has come into mind: using std::list; template < class Contents class Tree_node{ Contents cn; list < BTree_node < Contents children; ........
5
1754
by: emboss | last post by:
If templates worked how I would like them to work, I'd be able to do the following: template <int N> class A { private: int X; public: template <int M> void foo(const A<M> &Src) { X = Src.X; }
8
2964
by: flopbucket | last post by:
Hi, I want to provide a specialization of a class for any type T that is a std::map. template<typename T> class Foo { // ... };
0
9287
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9157
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9056
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8999
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6615
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5939
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4454
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4710
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2503
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.