GCC 和 Clang 都允许指定的初始化器引用正在初始化的结构或数组的成员,但是这是合法且定义良好的行为吗?
以下代码示例针对 GCC 和 Clang 进行编译和运行,并{ .a = 3, .b = 6, }在两种情况下输出:
#include <stdio.h>
typedef struct
{
int a;
int b;
} foo;
int main()
{
foo bar = {
.a = 3,
.b = bar.a + 3,
};
printf("{ .a = %d, .b = %d, }\n", bar.a, bar.b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC 为指定的初始化生成以下输出(编译器资源管理器链接),这表明该示例的操作是安全的:
mov dword ptr [rbp - 4], 0
mov dword ptr [rbp - 16], 3
mov eax, dword ptr …Run Code Online (Sandbox Code Playgroud) 我创建了一个与.xib文件关联的UIView子类.这个UIView子类将在UIViewController中使用.在控制器中,我认为我们实例化UIView子类有两种选择:
MyUIView *myView=[[MyUIView alloc] initWithFrame:aRect];
Run Code Online (Sandbox Code Playgroud)
和
MyUIView *myView = [[[NSBundle mainBundle] loadNibNamed:@"MyUIView"
owner:self
options:nil] lastObject];
Run Code Online (Sandbox Code Playgroud)
我更喜欢允许我执行自定义初始化的第一种方法或其变体.唯一的问题是我必须指定一个框架的rect,它已经在中指定了.xib(我的意思是框架的高度和宽度MyUIView).是的,我能再次硬编码aRect,但这是乏味的维护(例如,当我改变的.xib用户界面的位置,我需要更新aRect,太).
所以第二种方法应该在脑架自动设置时考虑到.剩下的问题是我无法自定义初始化程序(比方说,我想在初始化期间传递额外的参数).
你有什么偏好?你认为哪一个更好?
编辑1:受塞尔吉奥的回答启发,我推出了这个解决方法:
// In MyViewController.m
MyUIView *myView=[[MyUIView alloc] initWithFrame:CGRectMake(x, y, 0.0, 0.0)];
// In MyView.m
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
self = [[[NSBundle mainBundle] loadNibNamed:@"UnmovableTagView"
owner:self
options:nil] lastObject];
[self setFrame:CGRectMake(frame.origin.x,
frame.origin.y,
[self frame].size.width,
[self frame].size.height)];
// frame's width and height already determined after
// loadNibNamed was called
...
}
return self; …Run Code Online (Sandbox Code Playgroud) uiview designated-initializer ios initwithframe loadnibnamed
我想了解指定初始化程序提供的与直接初始化不同的内容。
例如:
#include <iostream>
struct Subject{
int x;
int y;
int z;
};
int main()
{
Subject subject_d{.x = 1, .y = 2, .z= 3};
Subject subject_c{1, 2, 3};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我们怎样才能把这两条线剥掉呢?对于细心的人,有什么区别?
以下指定初始值设定项示例在带有 /std:c++latest 的 Visual Studio 2019 中有效,但我想知道如何在 Visual Studio 2017 中没有指定初始值设定项的情况下完成相同的操作。
我正在使用 C++,我意识到有一种面向对象的方法可以做到这一点,但我并不是问如何使用构造函数在 C++ 中重新创建它。这使得这个问题的标签有点混乱,抱歉造成任何混乱。
我也在为这里的术语而苦苦挣扎。只是为了确认一下,是&(struct Foo)复合文字吗?这是实现编译时静态初始化吗?可以constexpr在这里用某种方式代替吗?
// Header
struct Foo
{
void (*Bar)();
};
extern struct Foo *FooAPI;
// Source
static void Bar()
{
}
static struct Foo *FooAPI = &(struct Foo) { // Error: Expecting an expression
.Bar = Bar
};
Run Code Online (Sandbox Code Playgroud) 在我尝试过的所有编译中,没有任何警告地接受以下 C++20 程序:
struct A { const int & x = z; int y = x; int z; };
int main()
{
return A{.z=3}.y;
}
Run Code Online (Sandbox Code Playgroud)
https://gcc.godbolt.org/z/nqb95zb7c
但是每个程序都会返回一些任意值。假设这是未定义的行为是否正确?
我有一个非常大的结构,它具有自定义的复制构造函数、自定义的移动构造函数、自定义的移动分配器和自定义的复制分配器,但我还需要在某处使用指定初始化语法来初始化它,因为它非常大,而我只想仅初始化其中的几个字段,其余字段保留默认值。
\n例如:
\nstruct SA_t {\n int a;\n int b;\n int c;\n};\n\nint main() {\n SA_t sa1 { .a = 2, .b = 3, .c = 4,}; // no problem\n return EXIT_SUCCESS;\n};\nRun Code Online (Sandbox Code Playgroud)\n但是当我为其添加自定义构造函数时,我根本无法使用指定初始化方法。
\nstruct SA_t {\n SA_t() {\n a = 0;\n b = 1;\n c = 2;\n };\n\n int a;\n int b;\n int c;\n};\n\nint main() {\n SA_t sa1 { .a = 2, .b = 3, .c = 4,}; /* no matching function for call to …Run Code Online (Sandbox Code Playgroud) c++ constructor initialization default-constructor designated-initializer