【问题标题】:Why am I getting error while initializing a struct with curly braces?为什么在使用花括号初始化结构时出现错误?
【发布时间】:2020-10-20 02:07:41
【问题描述】:

我正在使用以下代码并出现错误。我不明白为什么会出现此错误。

prog.cpp: In function ‘int main()’:
prog.cpp:15:44: error: could not convert ‘{"foo", true}’ from 
                       ‘<brace-enclosed initializer list>’ to ‘option’
                       option x[] = {{"foo", true},{"bar", false}};
                                            ^
prog.cpp:15:44: error: could not convert ‘{"bar", false}’ from 
                       ‘<brace-enclosed initializer list>’ o ‘option’

代码

#include <iostream>
#include <string>
 
struct option
{
    option();
    ~option();
 
    std::string s;
    bool b;
};
 
option::option() = default;
option::~option() = default;

int main()
{
    option x[] = {{"foo", true},{"bar", false}};
}

【问题讨论】:

  • 只需删除默认构造函数和析构函数,或者添加一个带有两个参数的构造函数。
  • 您编译的 C++ 版本是什么?每个版本的聚合规则都发生了变化,因此很重要。
  • IMO,我认为如果没有提供两个参数构造函数,大括号会减少 option 类的封装。为什么用户必须知道有两个成员变量可以这样设置?我可以理解像vector&lt;int&gt; 这样的东西,你知道你使用int 来填充对象,但是option?提供适当的构造函数,使option 由两个值组成,object 的构造函数计算出如何设置这些值。

标签: c++ c++11 initialization c++17 curly-braces


【解决方案1】:

当您提供默认构造函数和析构函数时,您正在使结构成为non-aggregate type, hence aggregate initialization 不可能。

但是,您可以使用标准 std::is_aggregate_v 特征检查类型是否为聚合。 (来自)。

See here for your case。它不是聚合,因为您提供了那些构造函数。

您有以下三种方法来完成这项工作:


下面的帖子解释了构造函数什么时候是defaulted,什么时候它被认为是用户声明的用户提供清楚:(Credits @NathanOliver

C++ zero initialization - Why is `b` in this program uninitialized, but `a` is initialized?

【讨论】:

  • 在不移除默认构造函数的情况下还有其他方法吗?
  • @AshutoshKumarRay 您可以添加一个带有两个参数的构造函数。
  • 这比你的回答看起来更微妙。例如,这编译得很好:coliru.stacked-crooked.com/a/856bbadf418fe86a
  • @JeJo 但这个是,并且它的成员明确默认为:godbolt.org/z/o6q-Z7
  • 当在类中声明一个构造函数为默认时,它被认为是一个用户声明的构造函数。在类外部默认它时,它是用户提供的构造函数。根据 C++ 的版本,如果它是聚合的,那将会有所不同。见:stackoverflow.com/questions/54350114/…
猜你喜欢
  • 1970-01-01
  • 2012-08-04
  • 2011-09-09
  • 2018-05-14
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-29
相关资源
最近更新 更多