【问题标题】:Having class inherit all operators of template type让类继承模板类型的所有运算符
【发布时间】:2021-04-24 00:16:15
【问题描述】:

我创建了这个类,所以我可以拥有任何类型的值,无论是固定的还是每次使用时重新计算的值:

template <typename T>
class DynamicValue {
    private:
    std::variant<T, std::function<T()>> getter;

    public:
    DynamicValue(const T& constant) : getter(constant){};
    template <typename F, typename = std::enable_if_t<std::is_invocable_v<F>>>
    DynamicValue(F&& function) : getter(function) {}
    DynamicValue(const T* pointer) : DynamicValue([pointer]() { return *pointer; }) {}
    DynamicValue(const DynamicValue& value) : getter(value.getter) {}
    ~DynamicValue() {}
    DynamicValue& operator=(const DynamicValue& value) {
        getter = value.getter;
        return *this;
    }
    operator T() {
        return getter.index() == 0 ? std::get<T>(getter) : std::get<std::function<T()>>(getter)();
    }
};

我还编写了以下虚拟结构来展示我的问题:

struct A {
    int b;
};

问题是,理想情况下,我可以将任何DynamicValue&lt;T&gt; 视为T 类型。因此,如果我要创建一个新值(DynamicValue&lt;A&gt; a = A{1};),我将能够执行a.b 并获得a 计算的值的属性b。但是,我收到以下错误:

“class DynamicValue”没有名为“b”的成员

您可以尝试一个现场示例here

我的问题是:有没有办法克服这个问题,还是我必须接受((A) a).b 语法?我曾考虑重载每个运算符以实现我的目标,但此解决方案不适用于 . 运算符(和其他运算符),它不可重载,并且可能会出现问题。

【问题讨论】:

    标签: c++ templates operator-overloading operators


    【解决方案1】:

    问题是,理想情况下,我可以将任何DynamicValue&lt;T&gt; 视为T 类型。所以如果我要创建一个新值(DynamicValue&lt;A&gt; a = A{1};),我就可以做到a.b 并得到a 计算的值的属性b。

    这需要operator. 重载或委托继承。两者都在 C++ 中不可用。

    我会推荐两个模型:operator() 重载或operator*

    重载调用操作符会让你的DynamicValue看起来像一个函数,无论它包含一个函数还是一个值:

    DynamicValue<A> a = A{1};
    
    auto real_a = a();
    std::cout << real_a.b;
    

    如果你重载解引用操作符,你的类看起来就像一个指向值的指针,无论它是一个值还是一个函数:

    DynamicValue<A> a = A{1};
    
    auto real_a = *a;
    std::cout << real_a.b;
    

    我会小心operator-&gt;,因为如果您的动态值包含函数,它可能会导致性能显着下降。

    我会完全避免隐式转换运算符,因为它带有很多警告和陷阱。这是一把很棒的霰弹枪,必须谨慎使用。

    【讨论】:

      猜你喜欢
      • 2020-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-01
      相关资源
      最近更新 更多