C++ Templates type casting with derivates

后端 未结 4 1376
离开以前
离开以前 2021-01-18 10:10

I\'m trying to cast from one generic to another, say:

myClass anItem = myclass anotherObject;


        
相关标签:
4条回答
  • 2021-01-18 10:49

    Templates in c++ aswell as generics in c++.net are not covariant.

    Check this question, might give you an idea for a workaround.

    0 讨论(0)
  • 2021-01-18 10:58

    Types aren't default convertible in this way (because you might not want objects to do that). In general, you could take two approaches:

    Implement a explicit cast function, which might be useful for runtime casts, like boost's shared_ptr dynamic_pointer_cast. You'd end up with something like:

    template <typename To, typename From>
    myclass<To> myclass_cast(const myclass<From>&)
    { /* do a runtime cast, possibly with exceptions */ }
    

    The second method is a converting constructor, which is good if it is decidable at compile time if they are convertable. For instance, if all classes are convertable from templated on Derived to templated on Base, here's a constructor that will only work when that is true (using enable_if and boost::type_traits):

    template <typename To>
    class myclass {
      //converting constructor
      template <typename From>
      myclass(const myclass<From>&,
              typename enable_if<boost::type_traits::is_base_of<To, From> >::type* dummy = 0)
      {  }
    };
    
    0 讨论(0)
  • 2021-01-18 11:01

    Sorry, that is not possible. (Well, unless you do nasty reinterpret_cast hacks, but you don't want to do that - the end result would not be pretty).

    T<Base> and T<Derived> are not related. Compiler cannot assume that - remember that it is entirely possible that T was specialized for Derived to be something completely different.

    0 讨论(0)
  • 2021-01-18 11:03

    You can't static cast, as they are incompatible types. You can sometimes create an operator to coerce the type instead

    #include <iostream>
    
    class A { };
    
    class B : public A { };
    
    
    template<typename T>
    struct holder {
        T* value;
    
        holder ( T*value ) : value ( value ) { }
    
        template < typename U > // class T : public U
        operator holder<U> () const
        {
            return holder<U>( value );
        }
    };
    
    
    int main ()
    {
        using namespace std;
    
        B   b;
    
        holder<B>   hb ( &b );
        holder<A>   ha  = hb;
    
        cout << boolalpha;
    
        cout << ( hb.value == ha.value ) << endl;
    
        return 0;
    }
    

    Whether this is a meaningful operation rather depends on the semantic of the template class - if the aFunction can put anything into the handler, you don't want the more specific object being mutated. Hence you copy somehow, either with a coercion operator or with a template copy constructor and assignment. ( the coercion is less code but might result in more objects being created if you don't use reference parameters )

    0 讨论(0)
提交回复
热议问题