Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Template Classes and Copy Construction

Tags:

c++

templates

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!

like image 956
themoondothshine Avatar asked Oct 15 '22 07:10

themoondothshine


1 Answers

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.

like image 160
Peter Alexander Avatar answered Oct 19 '22 01:10

Peter Alexander