tags:

views:

88

answers:

1

Is there any way I can construct an new object from the given object if the template parameters of both objects are identical at run-time? For example:

I have a template class with the declaration:

template<typename _Type1, typename _Type2> class Object;

Next, I have two instantiations of the template:

template class Object<char, int>;
template class Object<wchar_t, wint_t>;

Now, I want to write a member function such as:

template<typename _Type1, typename _Type2>
Object<char, int> Object<_Type1, _Type2>::toCharObject() {
    if(__gnu_cxx::__are_same<_Type1, char>::__value)
        return *this;
    else {
        //Perform some kind of conversion and return an Object<char, int>
    }
}

I have tried a couple of techniques, such as using __gnu_cxx::__enable_if<__gnu_cxx::__are_same<_Type1, char>::__value, _Type1>::__type in a copy constructor for the Oject class, but I keep running into the error:

error: conversion from ‘Object<wchar_t, wint_t>’ to non-scalar type ‘Object<char, int>’ requested

Is there no way I can do this? Any help will be greatly appreciated!

+4  A: 

What you have should work, the problem is that the compiler is doing a type check on the return *this part, even if the types aren't equal (hence the compile error). Just use return (Object<char, int>)(*this); and you should be fine -- the only time that code will be executed is when the types are the same anyway, so the cast does nothing other than working around the compile error.

Alternatively, you can use template specialisation:

template <class _Type1, class _Type2>
Object<char, int> toCharObject(Object<_Type1, _Type2> obj)
{
  // Do conversion and return
}

// Specialisation when types are equal
template <>
Object<char, int> toCharObject(Object<char, int> obj)
{
  return obj;
}

This is a free function as you can see. You can do it as a member function, but it's more tricky because you can't specialise individual member function -- you have to specialise the whole class. You can get around that by factoring out the non-specialised code, but that's really ugly, and this works just as well.

Peter Alexander
@Peter: You've hit the nail on the head!! I should have thought of template specialization sooner... I've used it in quite a few place already. Duh!!! Thanks a ton!
themoondothshine
@Peter: ...but somehow I can't get the casting to work. If I try to cast it, the compiler reports "error: invalid cast".
themoondothshine
Here's what worked though: `return Object<char, int>(*reinterpret_cast<const Object<char, int> *>(this))`
themoondothshine