Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在具有CRTP模式的派生类中使用聚合初始化?_C++_C++17_Crtp - Fatal编程技术网

C++ 如何在具有CRTP模式的派生类中使用聚合初始化?

C++ 如何在具有CRTP模式的派生类中使用聚合初始化?,c++,c++17,crtp,C++,C++17,Crtp,我使用的标准是c++17 问题是我想用CRPT重新生成代码并重新组织代码的结构,因为它非常适合,但问题是以前的代码在类中使用聚合初始化,如: ClassWithNoParent get(const T_& unit) const { return {.w = 1, .h = 1, .c = 1, .n = 1}; } 很好。当我使用CRTP时 class Defaul

我使用的标准是
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{});
}
class-DefaultClass{
公众:
int n;
INTC;
int-h;
int w;
};
模板
类BaseCRTPClass{
公众:
int w;
int-h;
INTC;
int n;
成功排序获取(constdefaultclass&)const{
返回{.w=1,
.h=1,
.c=1,
.n=1};
}
};
类继承者:public BaseCRTPClass{};
int main(){
继任者t;
autok=t.get(DefaultClass{});
}
编译失败,出现错误

21:25: error: could not convert '{1, 1, 1, 1}' from '<brace-enclosed initializer list>' to 'Successor'
21:25:错误:无法将“{1,1,1,1}”从“”转换为“继任者”
这是意料之中的,因为标准希望聚合
succession
,但是我不太确定
c++17
严格禁止没有基类。它限制了构造函数(正如我所理解的,但我可能错了)。那么,我怎样才能绕过这个问题呢

如何保持CRTP定义的派生类的聚合初始化


另外,我为什么要保留聚合初始化?因为我的代码中有很多地方都使用这种初始化,但是如果我在CRTP中重新生成,那么一切都将被破坏,我将不得不替换一些构造函数上的所有聚合初始化…

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

返回{{.w=1、.h=1、.c=1、.n=1};
举例来说,假设您有一个更简单的非模板类:

struct Base{int a;};
派生结构:公共基{int b;};
您必须将
Base
初始化为第一项:

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

继任者已经是一个聚合。这不是问题的根源。我不确定这到底是怎么回事,但看看吧。显然,指定
SuccessorT
并删除第一个参数的指定名称会使代码编译。指定成员初始值设定项是C++20的一项功能,不是核心C++17语言标准的一部分(但许多编译器提供的是作为扩展)。