Home > Software engineering >  C conversion operator for base type in templated wrapper
C conversion operator for base type in templated wrapper

Time:11-17

I'm trying to write a wrapper template class that allows conversion as if the templated type was used. I'm not sure how to write the template code to make this functional. See the code below:

class Base { }
class Derived : public Base { }

template <typename ObjectT>
class Wrapper {

    ...
    
    // Implicit conversion to base types
    template <class T, typename = std::enable_if_t<std::is_base_of<T, ObjectT>::value>>
    operator Wrapper<T>() const {
        return Wrapper<T>(data);
    };
    
    // Explicit conversion required for other types that are convertable
    template <class T, typename = std::enable_if_t< std::is_convertible<ObjectT, T>::value>>
    explicit operator Wrapper<T>() const {
        return Wrapper<T>(data);
    };
}

I would like to use Wrapper like this:

Wrapper<Base> wrapper = Wrapper<Derived>(); // Implicit conversion to base
Wrapper<float> wrapper = (Wrapper<float>)Wrapper<int>(); // float int requires explicit conversion, but is allowed

As of right now, this code gives me a compiler error since std::is_convertible<ObjectT, T> is also true for Base, Derived and thus creates the template function twice creating an ambiguous function

member function already defined or declared

CodePudding user response:

Try this:

template <typename ObjectT>
struct Wrapper {
  // Implicit conversion to base types
  template <class T, std::enable_if_t<std::is_base_of_v<T, ObjectT>>* = nullptr>
  operator Wrapper<T>() const;
  
  // Explicit conversion required for other types that are convertable
  template <class T, std::enable_if_t<
    !std::is_base_of_v<T, ObjectT> && std::is_convertible_v<ObjectT, T>>* = nullptr>
  explicit operator Wrapper<T>() const;
};

Demo.

  •  Tags:  
  • c
  • Related