【问题标题】:Heterogenous collection of CRTP-based polymorphic elements基于 CRTP 的多态元素的异构集合
【发布时间】:2020-07-18 12:19:13
【问题描述】:

让我们承认,出于任何正当理由,我们无法使用动态(虚拟)多态性。 CRTP 提供高效的静态多态性,如下所示:

template<typename derived_t>
struct Base {
    void sayFoo() { std::cout << "foo" << std::endl; }
    void sayBaz() { std::cout << impl().bazWord() << std::endl; } 
        
    derived_t& impl() { return static_cast<derived_t&>(*this); }
   
};

struct derived1 : public Base<derived1> {
    std::string bazWord() { return "baz1"; }
};

struct derived2 : public Base<derived2> {
    std::string bazWord() { return "baz2"; }
};

实例化很容易像这样完成:

derived1 d1;
d1.sayFoo(); // says "foo"
d1.sayBaz(); // says "baz1"

derived2 d2;
d1.sayFoo(); // says "foo"
d2.sayBaz(); // says "baz2"

现在,我想将这些元素保存在一个异构集合中,如下所示:

std::vector<Base<??>> v;
v.push_back(d1);
v.push_back(d2);
std::for_each(v.begin(), v.end(), [](auto& elem) { elem.sayBaz(); })

这样做会给我一个错误,显然是因为无法定义基本类型。

有没有简单的方法来实现基于 CRTP 的异构集合?

【问题讨论】:

  • 您可以使用runtime-concept idiom,它不需要接口级别的运行时多态性,但您仍然需要在实现级别具有运行时多态性。 youtu.be/QGcVXgEVMJg 链接将为您提供有关 Sean Parent 机制的良好信息。

标签: c++ collections polymorphism c++17 crtp


【解决方案1】:

最简单的解决方案(但可能不是最优雅的)是使用std::tuple。以下示例效果很好:

auto coll = std::make_tuple(d1, d2);
std::apply([&](auto & ... el) { 
    (..., el.sayBaz());
}, coll);

迭代不是直截了当的,它具有std::tuple 的所有优点和缺点(主要是没有运行时插入),但至少它有效!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    • 2021-08-17
    • 2020-01-25
    • 1970-01-01
    • 2012-10-29
    • 2017-07-17
    • 2018-07-18
    相关资源
    最近更新 更多