假设我有一些带有删除拷贝构造函数的类:
struct NoCopy
{
NoCopy(int) {}
NoCopy(const NoCopy &) = delete;
};
Run Code Online (Sandbox Code Playgroud)
我在另一个类中使用这个类:
struct Aggregate
{
NoCopy nc;
};
Run Code Online (Sandbox Code Playgroud)
但是当我尝试使用聚合初始化时
int main()
{
Aggregate a{3};
}
Run Code Online (Sandbox Code Playgroud)
编译器输出以下错误:
error: use of deleted function ‘NoCopy::NoCopy(const NoCopy&)’
Run Code Online (Sandbox Code Playgroud)
为什么聚合初始化需要类成员的副本构造函数?聚合初始化是否使用复制构造函数初始化所有成员?
我有一个包含位字段的结构:
struct Foo {
unsigned a : 16, b : 16;
};
Run Code Online (Sandbox Code Playgroud)
我想知道我是否可以在它的位字段上使用聚合初始化.例如:
struct Foo bar = {13, 42};
Run Code Online (Sandbox Code Playgroud)
我注意到这在gcc 5.1和Visual Studio 2015中都有效.我只想要证明这是C和C++的标准批准初始化.
我想知道当初始化程序多于数组大小时会发生什么,例如:
int t[3] = { 1, 2, 3, 4 };
Run Code Online (Sandbox Code Playgroud)
当然,我的编译器警告它.我期望未定义的行为,但我没有在C11标准中找到任何关于它的条款.那么,我错过了什么吗?
c arrays initialization object-initializers aggregate-initialization
从聚合初始化,将指针设置为 struct member,以下代码合法:
struct S
{
int a;
int* aptr;
};
S s = { 3, &s.a };
Run Code Online (Sandbox Code Playgroud) c++ initialization object-lifetime language-lawyer aggregate-initialization
我试图找到确认或反驳以下声明的文件
char test[5]="";
Run Code Online (Sandbox Code Playgroud)
导致缓冲区初始化为所有与
memset(test,'\0',sizeof(test));
Run Code Online (Sandbox Code Playgroud)
但一直无法找到(或理解/破译)任何东西。我专门寻找旧规范中的细节,C99 参考也可以使用。谢谢
c arrays string-literals language-lawyer aggregate-initialization
据我了解,以下程序应该在 C++20 模式下工作:
#include <vector>
struct B{ int a0, a1; };
int main()
{
std::vector<B> bs;
bs.emplace_back( 0, 0 );
}
Run Code Online (Sandbox Code Playgroud)
它在 Visual Studio 2019 和 gcc 11 中确实如此。但不是在 clang 12 中,这会产生错误:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/alloc_traits.h:514:4: error: no matching function for call to 'construct_at'
std::construct_at(__p, std::forward<_Args>(__args)...);
^~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
在在线编译器中:https : //gcc.godbolt.org/z/GzccTWc5z
这是因为 clang 还没有完全支持 C++20 吗?
假设有以下代码片段:
#include <optional>
struct MyStruct
{
// MyStruct(int a) : a(a) {}
int a;
};
int main()
{
std::optional<MyStruct> ms1 = std::make_optional<MyStruct>(1);
std::optional<MyStruct> ms2{2};
std::optional<MyStruct> ms3;
ms3.emplace(3);
std::optional<MyStruct> ms4(std::in_place, 4);
}
Run Code Online (Sandbox Code Playgroud)
这按预期使用 c++20 和 gcc 11.2 工作,所有这四种创建方法都在 clang 上编译失败(编译器资源管理器链接)
为了使其与 clang 一起工作,我需要取消注释构造函数。
我的主要问题是:clang 还是 gcc 哪个编译器是正确的?
后续问题:如果 clang 是正确的,是否有任何方法可以在可选中创建没有构造函数的结构,而不将结构复制到其中,例如std::optional<MyStruct> ms{MyStruct{3}}?
我正在编写一个由多个 s 组成的大型固定大小整数类型uint64_t,如下面的(简化的)示例所示。我希望我的类型表现得像内置整数类型,这意味着(除其他外):
然而,在我看来,人们无法编写一种同时满足这两个属性的类型。这是因为属性 1 要求类型是聚合,这意味着它必须没有构造函数,而我们需要一个构造函数来实现属性 2。
有没有办法编写一个满足这两个属性的大整数类型?
#include <array>
#include <cstdint>
struct uint128_t{
std::array<uint64_t, 2> data;
};
int main(){
uint128_t x; // uninitialized (good)
uint128_t y = 100; // can we make this work while ensuring that the previous line still works?
}
Run Code Online (Sandbox Code Playgroud) 众所周知,在 C++20 中,具有用户声明的构造函数的类不是聚合的。
现在,考虑以下代码:
#include <type_traits>
template <bool EnableCtor>
struct test {
template <bool Enable = EnableCtor, class = std::enable_if_t<Enable>>
test() {}
int a;
};
int main() {
test<false> t {.a = 0};
}
Run Code Online (Sandbox Code Playgroud)
GCC 和 CLang 都不会编译此代码。因此,尽管这里没有实例化的构造函数,但该类不是聚合。
构造函数模板是否被视为“声明的构造函数”?对于这种情况,标准有何规定?
请参阅此答案,以了解如何在不复制地图值的情况下将其插入到stdmap中。
继续回答-假设我的Foo类型如下所示:
struct Foo {
const int& intref_;
std::mutex mutex_;
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用聚合初始化来初始化
Foo{7}
Run Code Online (Sandbox Code Playgroud)
要么
Foo{7, std::mutex()}
Run Code Online (Sandbox Code Playgroud)
是否可以通过类型将其放置到地图中?
std::map<size_t, Foo> mymap;
Run Code Online (Sandbox Code Playgroud)
我知道我可以为此写一个构造函数,Foo但是可以用聚合初始化来代替吗?
链接到编译器资源管理器:
相关的c ++参考:
https://en.cppreference.com/w/cpp/container/map/try_emplace
https://en.cppreference.com/w/cpp/language/aggregate_initialization