【问题标题】:C++ conversion operator for base type in templated wrapper模板化包装器中基类型的 C++ 转换运算符
【发布时间】:2021-11-16 17:17:40
【问题描述】:

我正在尝试编写一个允许转换的包装模板类,就像使用模板类型一样。我不确定如何编写模板代码以使其正常工作。请看下面的代码:

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);
    };
}

我想像这样使用 Wrapper:

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

到目前为止,这段代码给了我一个编译器错误,因为 std::is_convertible 对于 Base, Derived 也是如此,因此创建了两次模板函数,从而创建了一个模棱两可的函数

member function already defined or declared

【问题讨论】:

  • 如果is_convertable &amp;&amp; !is_base_of,你能不能只启用第二个运算符?
  • @vandench 完全不知道怎么用模板写这个
  • IIRC enable_if 的第一个模板参数只是一个布尔值,is_convertibleis_base_of 的值成员都是布尔值,所以它应该像我给出的文字示例一样简单,尽管使用模板参数并访问值成员。

标签: c++


【解决方案1】:

试试这个:

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.

【讨论】:

  • 成功了,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-05
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 2020-11-30
相关资源
最近更新 更多