【问题标题】:Calling automatic constructor: why is my type incomplete?调用自动构造函数:为什么我的类型不完整?
【发布时间】:2019-03-13 09:37:09
【问题描述】:

在下面的代码中,我想使用默认构造函数{.data = value},因为我希望我的类是POD。我不明白编译时收到的错误消息(llvm 或 gnu,c++11):

#include <type_traits>

class a {
  char data;
  static inline a create(char c) { return {.data = c}; } // this fails
  static inline a create2(char c) { a x; x.data = c; return x; } // this is OK
public:
  void init(char c) { *this = create(c); }
};

int main() {
  a s;
  s.init('x');
  return std::is_pod<a>::value;
}

有错误信息

t.cc:5:43: error: no matching constructor for initialization of 'a'
  static inline a create(char c) { return {.data = c}; }
                                          ^~~~~~~~~~~
t.cc:3:7: note: candidate constructor (the implicit copy constructor) not viable: cannot convert
      argument of incomplete type 'void' to 'const a &'

哪位好心人能解释一下为什么我想使用 a 的类型不完整,为什么它被视为void

【问题讨论】:

  • 在 C++20 之前不存在指定初始化器,您是否使用了编译器扩展?
  • 你为什么不写一个 constructor (a(char c) : data(c) { }) 或一组?
  • @Quentin:在我尝试过的所有系统上,它都可以使用 -std=c++11 进行正常编译。
  • @rubenvb - 没有人们想象的那么严格。 GCC 和 Clang 确实需要一个 -pedantic 标志才能非常严格。
  • @grok std::is_pod 现在在 C++ 20 中已被弃用,所以我建议使用 std::is_trivialstd::is_standard_layout

标签: c++ c++11 types compiler-errors


【解决方案1】:

您不能聚合初始化私有成员。

来自https://en.cppreference.com/w/cpp/language/aggregate_initialization

聚合是以下类型之一:... 类类型(通常是结构或联合),没有私有或受保护的非静态数据成员

因为aclass,而不是struct,所以dataprivate

data 声明为public,或将类型声明为struct 以将其默认为public

然后替换static inline a create(char c) { return {.data = c}; }

static inline a create(char c) { return a { c }; }

https://en.cppreference.com/w/cpp/language/list_initialization

直接列表初始化(2)

【讨论】:

  • 另外,您使用我的更改编写的程序返回 1(表示错误),因为 true 隐式转换为 1。使用 MSVC 14 编译和运行。
猜你喜欢
  • 1970-01-01
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-07
  • 2015-04-24
  • 1970-01-01
相关资源
最近更新 更多