template confusion

F

Floogle

I cannot figure out why the following program instantiates two type
"2" instances instead of one "1" and one "2".

Could someone plz enlighten me?

Many thanks

Here's the code

-------------------------------------------------------------------------------
#include <iostream>
using namespace std;

class Base
{
public:

virtual int GetType()const=0;
};

class Dev1 : public Base
{
public:

int GetType()const{return 1;}
};

class Dev2 : public Base
{
public:

int GetType()const{return 2;}
};

struct BaseHolder
{
Base* pBase;

BaseHolder(Base* pB):pBase(pB)
{}
};

template <class T>
BaseHolder CreateABaseHolder()
{
return BaseHolder(new T());
}


int main()
{
BaseHolder h1 = CreateABaseHolder<Dev1>();
BaseHolder h2 = CreateABaseHolder<Dev2>();

cout << "\nID of base in h1 (should be == 1) = " <<
h1.pBase->GetType();
cout << "\nID of base in h2 (should be == 2)= " <<
h2.pBase->GetType();

return 0;
}
-------------------------------------------------------------------------
 
?

=?ISO-8859-1?Q?Stefan_N=E4we?=

Floogle said:
I cannot figure out why the following program instantiates two type
"2" instances instead of one "1" and one "2".

Could someone plz enlighten me?

Many thanks

Here's the code

-------------------------------------------------------------------------------
#include <iostream>
using namespace std;

class Base
{
public:

virtual int GetType()const=0;
};

class Dev1 : public Base
{
public:

int GetType()const{return 1;}
};

class Dev2 : public Base
{
public:

int GetType()const{return 2;}
};

struct BaseHolder
{
Base* pBase;

BaseHolder(Base* pB):pBase(pB)
{}
};

template <class T>
BaseHolder CreateABaseHolder()
{
return BaseHolder(new T());
}


int main()
{
BaseHolder h1 = CreateABaseHolder<Dev1>();
BaseHolder h2 = CreateABaseHolder<Dev2>();

cout << "\nID of base in h1 (should be == 1) = " <<
h1.pBase->GetType();
cout << "\nID of base in h2 (should be == 2)= " <<
h2.pBase->GetType();

return 0;
}
-------------------------------------------------------------------------

I get this:


$ ./baseholder

ID of base in h1 (should be == 1) = 1
ID of base in h2 (should be == 2) = 2


On which planet did you compile this?

/S
 
F

Floogle

I get this:


$ ./baseholder

ID of base in h1 (should be == 1) = 1
ID of base in h2 (should be == 2) = 2


On which planet did you compile this?

/S


On planet MSVC6
 
?

=?ISO-8859-1?Q?Stefan_N=E4we?=

Floogle said:
On planet MSVC6

OK.
I initially tried that with GCC 3.4.4 from Cygwin.

The test with MSVC gave me:

$ ./baseholder.exe

ID of base in h1 (should be == 1) = 2
ID of base in h2 (should be == 2) = 2


I'm confused, too!
It's probably one more of those annoying MSVC stupidities...


/S
 
B

Ben Pope

Floogle said:
Alas, it's not that simple. It has to work using MSVC6... :eek:(

It never is. I have an MSVC6 program, having spent the time to port it
to MSVC2005 it now behaves "strangely".

With MSVC6 you are restricting your template abilities considerably...
Perhaps you can poke around within boost code for MSVC6 workarounds.

Good luck.

Ben Pope
 
?

=?ISO-8859-1?Q?Stefan_N=E4we?=

Gernot said:
Lokks like a bug rather than a stupidity.

It's a stupidity when you can get around it:

<----CODE---->

#include <iostream>
using namespace std;

class Base
{
public:
virtual ~Base() { }
virtual int GetType()const=0;
};

class Dev1 : public Base
{
public:

int GetType()const{return 1;}
};

class Dev2 : public Base
{
public:

int GetType()const{return 2;}
};

struct BaseHolder
{
Base* pBase;

BaseHolder(Base* pB):pBase(pB)
{}
};

template<typename T>
struct TypeHolder
{
typedef T OriginalType;
};

template <class T>
BaseHolder CreateABaseHolder(TypeHolder<T>)
{
return BaseHolder(new T());
}

int main()
{
BaseHolder h1 = CreateABaseHolder(TypeHolder<Dev1>());
BaseHolder h2 = CreateABaseHolder(TypeHolder<Dev2>());

cout << "\nID of base in h1 (should be == 1) = " << h1.pBase->GetType();
cout << "\nID of base in h2 (should be == 2) = " << h2.pBase->GetType();

return 0;
}

<----/CODE---->

/S
 
B

Bo Persson

Floogle said:
Alas, it's not that simple. It has to work using MSVC6... :eek:(


It is a known bug in VC6, that function templates that don't use the
template as a function parameter will confuse the linker. If you have
several overloads, one of them will be used (at random).

template <class T>
BaseHolder CreateABaseHolder()
{
return BaseHolder(new T());
}

doesn't work (as you have noticed).

The solution is to add a dummy parameter of type T, to generate a
different internal name.

template <class T>
BaseHolder CreateABaseHolder(const T* dummy = 0)
{
return BaseHolder(new T());
}

will work!


Bo Persson
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top