如何为派生类提供静态方法的“一揽子实现”?

问题描述 投票:0回答:1

考虑一下:

struct Base {
  static Base make() { return {}; }
};

struct Derived {
  // I _would_ want to have a `static Derived make()` automagically here
};

解决上述问题的一种方法是

struct Base {
  template <typename Self>
  static Self make() { return {}; }
};

struct Derived {
  static constexpr auto make = Base::make<Derived>;
};

,但它不会在重载的情况下工作,而且我do需要它在重载的情况下工作......

还有更好的选择吗?

c++ inheritance static-methods
1个回答
0
投票

不幸的是,不可能做你想做的事情,但有一些替代方案,具体取决于你在代码中的实际目标。

首先要注意的是,重载静态方法并不是那么有趣,因为无论如何你只能使用静态分派来调用它,这几乎违背了除了代码组织之外的要点。演示您是否有以下代码(并且

magic_type
以某种方式存在)。

struct Base {
    static magic_type make() { return {}; }
};

struct Derived : public Base {
    static magic_type make() { return {}; }
};

然后您必须将这些方法调用为

Base::make()
Derived::make()
。如果这是可以接受的,那么我建议使用模板专业化。

template <typename T>
T make(){
    return T();
}

template <>
Base make<Base>(){
    return Base();
}

template <>
Derived make<Derived>(){
    return Derived();
}

可能在某个名称空间中,以避免与其他名为

make
的内容发生冲突。然后调用此代码将是
make<Base>()
make<Derived>()
,这在灵活性方面几乎相同。

如果你真正想要的是重写

make
方法,并且想要动态调度(这意味着不使函数静态),那么它仍然不太可能。您可以使用名称遮蔽来获取看起来大致正确的代码,但这是不好的做法,并且可能不会执行您想要的操作(我避免添加示例,因为它不应该执行并且无论如何也不会给您动态调度) 。或者,您可以返回一个指针,这可能是最接近您的目标的解决方案。

struct Base {
    std::unique_ptr<Base> make() {
        return std::make_unique<Base>();
    }
};

struct Derived : public Base {
    std::unique_ptr<Base> make() {
        return std::unique_ptr((Base*)(new (std::nothrow) Derived()));
    }
};

几乎可以肯定有一种更好的方法来创建 Derived,但目前已经足够好了。

这绝对与您最初的请求不同,并且考虑到您的实际目标,这可能是不可接受的,但我希望这两种可能的解决方案之一适合您,或者至少提示您找到适合您的特定用例的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.