繁体   English   中英

如何在带有 CRTP 模式的派生 class 中使用聚合初始化?

[英]How to use aggregated initialization in derived class with CRTP pattern?

我使用的标准是c++17

问题是我想重新制作我的代码并用 CRPT 重新组织我的代码结构,因为它非常适合但问题是以前的代码在类中使用聚合初始化,例如:

ClassWithNoParent get(const T_& unit) const {
        return {.w = 1,
                .h = 1,
                .c = 1,
                .n = 1};
    }

没关系。 当我使用 CRTP

class DefaultClass {
 public:
    int n;
    int c;
    int h;
    int w;
};

template <class SuccessorT, class T = DefaultClass>
class BaseCRTPClass {
 public:
    int w;
    int h;
    int c;
    int n;

    SuccessorT get(const DefaultClass&) const {
        return   {.w = 1,
                  .h = 1,
                  .c = 1,
                  .n = 1};
    }
};

class Successor : public BaseCRTPClass<Successor> {};

int main(){
    Successor t;
    auto k = t.get(DefaultClass{});
}

编译失败并出现错误

21:25: error: could not convert '{1, 1, 1, 1}' from '<brace-enclosed initializer list>' to 'Successor'

这是预期的,因为标准希望聚合Successor ,但是我不太确定c++17严格禁止没有基数 class。它限制构造函数(据我了解,但我可能是错的)。 那么,我怎样才能绕过这个问题呢?

如何保留 CRTP 定义的派生 class 的聚合初始化?

PS 为什么要保留聚合初始化? 因为我的代码中的很多地方都使用了这个初始化,但是如果将在 CRTP 中重新制作,那么一切都会被粉碎,我将不得不替换一些构造函数上的所有聚合初始化......

该问题与 CRTP 无关。 派生类的聚合初始化仅在 C++17 中引入。要聚合初始化派生类 class,必须将基类 class 初始化为其自己的初始化列表中的第一项。 因此,要使其正常工作,请使用双支撑:

return {{.w = 1, .h = 1, .c = 1, .n = 1}};

为了说明这一点,假设您有一个更简单的非模板 class:

struct Base { int a; };
struct Derived : public Base { int b; };

您必须将Base初始化为第一项:

Derived x = { 
    { .a = 42 }, // Base
    .b = 24      // b
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM