Template parameter interpreted as base, not derived
-
I have a template function to check the type passed to it. I am templatizing it on a derived type but when I break in the function, the template parameter is the base class. A sample app is below. Can someone please explain where I am going wrong? Thanks
class Base
{
public:
virtual ~Base() {}
};class Derived1 : public Base {};
class Derived2 : public Base {};
template<class T> bool CheckType(boost::shared_ptr<Base> pBase)
{
T* pTemplate = NULL; //Why is pTemplate Base* and not Derived1* when passing a Derived1 to template parameter?
Base* pBaseRaw = pBase.get();
if(typeid(pBaseRaw) == typeid(pTemplate))
{
return true;
}return false;
}
int _tmain(int argc, _TCHAR* argv[])
{
boost::shared_ptr<Base> pBase1(new Derived1);
boost::shared_ptr<Base> pBase2(new Derived2);
bool bIsDerived = CheckType<Derived1>(pBase1);
bIsDerived = CheckType<Derived2>(pBase2);return 0;
}
-
I have a template function to check the type passed to it. I am templatizing it on a derived type but when I break in the function, the template parameter is the base class. A sample app is below. Can someone please explain where I am going wrong? Thanks
class Base
{
public:
virtual ~Base() {}
};class Derived1 : public Base {};
class Derived2 : public Base {};
template<class T> bool CheckType(boost::shared_ptr<Base> pBase)
{
T* pTemplate = NULL; //Why is pTemplate Base* and not Derived1* when passing a Derived1 to template parameter?
Base* pBaseRaw = pBase.get();
if(typeid(pBaseRaw) == typeid(pTemplate))
{
return true;
}return false;
}
int _tmain(int argc, _TCHAR* argv[])
{
boost::shared_ptr<Base> pBase1(new Derived1);
boost::shared_ptr<Base> pBase2(new Derived2);
bool bIsDerived = CheckType<Derived1>(pBase1);
bIsDerived = CheckType<Derived2>(pBase2);return 0;
}
A few questions:
- If I understand you correctly, CheckType is returning true, but you expected false?
- What compiler (& version) are you using?
I've just tried your code with g++ 4.0.1 and it gives the results I'd expect. I added some code to print out type names:
template<class T> bool CheckType(boost::shared_ptr<Base> pBase)
{
std::cout << typeid(T).name() << std::endl;
T* pTemplate = NULL; //Why is pTemplate Base* and not Derived1* when passing a Derived1 to template parameter?
Base* pBaseRaw = pBase.get();
std::cout << typeid(pBaseRaw).name() << std::endl;
if(typeid(pBaseRaw) == typeid(pTemplate))
{
return true;
}return false;
}
. I also printed out the result of CheckType and got these results:
8Derived1
P4Base
0
8Derived2
P4Base
0So - the template parameter is Derived, the parameter is a pointer to Base, CheckType is returning false. I'm suspecting that the compiler you're using isn't fully standard compliant if it does something different?
-
I have a template function to check the type passed to it. I am templatizing it on a derived type but when I break in the function, the template parameter is the base class. A sample app is below. Can someone please explain where I am going wrong? Thanks
class Base
{
public:
virtual ~Base() {}
};class Derived1 : public Base {};
class Derived2 : public Base {};
template<class T> bool CheckType(boost::shared_ptr<Base> pBase)
{
T* pTemplate = NULL; //Why is pTemplate Base* and not Derived1* when passing a Derived1 to template parameter?
Base* pBaseRaw = pBase.get();
if(typeid(pBaseRaw) == typeid(pTemplate))
{
return true;
}return false;
}
int _tmain(int argc, _TCHAR* argv[])
{
boost::shared_ptr<Base> pBase1(new Derived1);
boost::shared_ptr<Base> pBase2(new Derived2);
bool bIsDerived = CheckType<Derived1>(pBase1);
bIsDerived = CheckType<Derived2>(pBase2);return 0;
}
Member 2603772 wrote:
T* pTemplate = NULL; //Why is pTemplate Base* and not Derived1* when passing a Derived1 to template parameter?
nope, you confused with the result, check by printing
std::cout << typeid(pTemplate).name()
I think you expected the result as true and you got false (bIsDerived = true you expected, as the pointer you passed is derived). to get what inside the pointer you can dereference it saytypeid(*pBaseRaw)
so your code can be,template<class T> bool CheckType(boost::shared_ptr<Base> pBase)
{
Base* pBaseRaw = pBase.get();
if(typeid(*pBaseRaw) == typeid(T)) {
return true;
}
return false;
}modified on Friday, January 23, 2009 1:13 PM
-
A few questions:
- If I understand you correctly, CheckType is returning true, but you expected false?
- What compiler (& version) are you using?
I've just tried your code with g++ 4.0.1 and it gives the results I'd expect. I added some code to print out type names:
template<class T> bool CheckType(boost::shared_ptr<Base> pBase)
{
std::cout << typeid(T).name() << std::endl;
T* pTemplate = NULL; //Why is pTemplate Base* and not Derived1* when passing a Derived1 to template parameter?
Base* pBaseRaw = pBase.get();
std::cout << typeid(pBaseRaw).name() << std::endl;
if(typeid(pBaseRaw) == typeid(pTemplate))
{
return true;
}return false;
}
. I also printed out the result of CheckType and got these results:
8Derived1
P4Base
0
8Derived2
P4Base
0So - the template parameter is Derived, the parameter is a pointer to Base, CheckType is returning false. I'm suspecting that the compiler you're using isn't fully standard compliant if it does something different?
Thanks for the response. Your output is what I expected. I was looking at the pointer types in the debugger, not printing out the type info to the console. The print statements give me what you got. I am using VS2008 v9 SP1. I was performing the wrong check to get a type match. I changed the function to the following:
template<class T> bool CheckType(boost::shared_ptr<Base> pBase)
{
Base* pBaseRaw = pBase.get();
if(pBaseRaw == null)
{
return false;
}if(typeid(\*pBaseRaw) == typeid(T)) //Now dereferencing pBaseRaw. Bad idea? { return true; } return false;
}
I am now dereferencing the base class pointer returned from shared_ptr which casts it to the right type. I believe this is a sketchy implicit cast to the derived type. Should I just dynamic_cast or does the typeid comparison take care of type issues? Thanks:thumbsup:
-
Member 2603772 wrote:
T* pTemplate = NULL; //Why is pTemplate Base* and not Derived1* when passing a Derived1 to template parameter?
nope, you confused with the result, check by printing
std::cout << typeid(pTemplate).name()
I think you expected the result as true and you got false (bIsDerived = true you expected, as the pointer you passed is derived). to get what inside the pointer you can dereference it saytypeid(*pBaseRaw)
so your code can be,template<class T> bool CheckType(boost::shared_ptr<Base> pBase)
{
Base* pBaseRaw = pBase.get();
if(typeid(*pBaseRaw) == typeid(T)) {
return true;
}
return false;
}modified on Friday, January 23, 2009 1:13 PM
Thanks. I just posted a similar result based on the previous response. I appreciate the help.:thumbsup:
-
Thanks for the response. Your output is what I expected. I was looking at the pointer types in the debugger, not printing out the type info to the console. The print statements give me what you got. I am using VS2008 v9 SP1. I was performing the wrong check to get a type match. I changed the function to the following:
template<class T> bool CheckType(boost::shared_ptr<Base> pBase)
{
Base* pBaseRaw = pBase.get();
if(pBaseRaw == null)
{
return false;
}if(typeid(\*pBaseRaw) == typeid(T)) //Now dereferencing pBaseRaw. Bad idea? { return true; } return false;
}
I am now dereferencing the base class pointer returned from shared_ptr which casts it to the right type. I believe this is a sketchy implicit cast to the derived type. Should I just dynamic_cast or does the typeid comparison take care of type issues? Thanks:thumbsup:
IIRC, typeid uses the same mechanism as dynamic_cast, so typeid on its own is fine.