是否可以在C++中初始化结构,如下所示
struct address {
int street_no;
char *street_name;
char *city;
char *prov;
char *postal_code;
};
address temp_address =
{ .city = "Hamilton", .prov = "Ontario" };
Run Code Online (Sandbox Code Playgroud)
这里和这里的链接提到可以仅在C中使用此样式.如果是这样,为什么在C++中这是不可能的?是否有任何潜在的技术原因导致它没有在C++中实现,或者使用这种风格是不好的做法.我喜欢使用这种初始化方式,因为我的结构很大,这种风格让我清楚地看到了为哪个成员分配了什么值.
如果有其他方法可以达到相同的可读性,请与我分享.
在发布此问题之前,我已经提到了以下链接
在阅读文章时,我遇到了以下功能:
SolidColor::SolidColor(unsigned width, Pixel color)
: _width(width),
_color(color) {}
__attribute__((section(".ramcode")))
Rasterizer::RasterInfo SolidColor::rasterize(unsigned, Pixel *target) {
*target = _color;
return {
.offset = 0,
.length = 1,
.stretch_cycles = (_width - 1) * 4,
.repeat_lines = 1000,
};
}
Run Code Online (Sandbox Code Playgroud)
作者用return语句做了什么?我之前没有见过这样的东西,我不知道如何搜索它...它对普通C也有效吗?
编辑: 链接到原始文章
根据标准:
执行字符集的成员值是实现定义的.
(ISO/IEC 9899:1999 5.2.1/1)
进一步在标准中:
...
0在上面的十进制数字列表中,每个字符的值应大于前一个值的值.
(ISO/IEC 9899:1999 5.2.1/3)
似乎标准要求执行字符集包括拉丁字母表的26个大写字母和26个小写字母,但我认为不要求以任何方式对这些字符进行排序.我只看到十进制数字的订单规定.
这似乎意味着,严格来说,不能保证'a' < 'b'.现在,字母表中的字母按顺序分为ASCII,UTF-8和EBCDIC.但对于ASCII和UTF-8,我们有'A' < 'a',而对于EBCDIC,我们有'a' < 'A'.
有一个函数可以很好地ctype.h比较字母字符可移植.缺少这个或类似的东西,在我看来,必须在区域设置中查找值CODESET并继续相应地进行,但这似乎并不简单.
我的直觉告诉我,这几乎不是问题; 对于大多数情况,可以通过转换为小写来处理字母字符,因为对于最常用的字符集,字母是有序的.
问题是:给出两个字符
char c1;
char c2;
Run Code Online (Sandbox Code Playgroud)
有一个简单的,可移植的方式来确定c1之前c2按字母顺序排列?或者我们是否假设小写和大写字符总是按顺序出现,即使标准似乎没有保证这一点?
为了澄清任何混淆,我真的只对拉丁字母的52个字母感兴趣,这些字母由标准保证在执行字符集中.我意识到其他字母组很重要,但似乎我们甚至无法知道这一小部分字母的排序.
我想我需要澄清一点.我认为,问题在于我们通常认为拉丁字母的26个小写字母是有序的.我希望能够断言"a"出现在'b'之前,并且我们有一种方便的方式在代码中表达它,因为'a' < 'b'当我们给出'a'和'b'整数值时.但该标准不保证上述代码将按预期进行评估.为什么不?该标准确实保证了数字0-9的这种行为,这似乎是明智的.如果我想确定一个字母字符是否在另一个字母之前,比如用于排序目的,并且如果我希望这个代码真正可移植,那么标准似乎没有帮助.现在我必须依赖ASCII,UTF-8,EBCDIC等采用的惯例'a' < 'b'.但是,除非使用的唯一字符集依赖于此约定,否则这不是真正可移植的; 这可能是真的.
这个问题起源于另一个问题主题:检查一封信是在C之前或之后的另一个字母.在这里,一些人建议您可以char使用不等式确定存储在s中的两个字母的顺序.但是一位评论者指出,标准并不能保证这种行为.
我需要将值转换为人类可读的字符串.通常对于我定义的东西,我会使用从零开始的值,并创建一个简单的字符串数组,其值为索引.
static const char *foo[] = { "foo", "bar", "etc" };
if (val < 3) printf("%s\n", foo[val]);
Run Code Online (Sandbox Code Playgroud)
对于这种情况,我的值不是从零开始,它们之间存在一些差距.有没有一个很好的方法来做到这一点,而不必手动编码索引的一堆空字符串没有匹配的值/字符串对?
static const char *foo[] = { "", "", "", "foo", "", "bar", "", "", "etc" };
Run Code Online (Sandbox Code Playgroud) C99引入了结构指定的初始化器的概念.例如,给定:
typedef struct {
int c;
char a;
float b;
} X;
Run Code Online (Sandbox Code Playgroud)
我可以初始化为:X foo = {.a = '\1', .b = 2.0F, .c = 4};并且调用:printf("c = %d\na = %hhu\nb = %f", foo.c, foo.a, foo.b);将输出:
c = 4
a = 1
b = 2.000000
这里提到这有分配给的"令人惊讶的行为" c,然后a再b独立我指定的初始的顺序.
如果我有这样的函数,这将成为一个真正的问题:
int i = 0;
int f() {
return ++i;
}
int g() {
i += 2;
return i;
}
int h() {
i += 4; …Run Code Online (Sandbox Code Playgroud) 这是受到这篇文章的启发,其中 不支持非平凡的指定初始化程序。
我已经阅读了这篇文章,一些答案声称已经支持此功能。
但是,使用 C++17 和此代码:
struct s {
int a[2];
s (int b): a{[1]=b} {} // error
};
s foo(1);
Run Code Online (Sandbox Code Playgroud)
我仍然收到错误:
抱歉,未实现:不支持非平凡的指定初始值设定项
s (int b): a{[1]=b} {}
我在想这个功能真的很有帮助。
所以我的问题:
是否有计划在未来的 C++ 版本(C++17 后)中支持它?
编译器
GNU C++17 - 检查魔杖盒
我试图在派生自模板结构上使用struct初始化.代码如下:
template <class Derived>
struct Event{
//the level of access on the ctor has nothing to do with the problem
//protected:
// Event() = default;
};
struct MoveEvent: Event<MoveEvent>{
int x, y;
};
int main(){
//how do I make this work?
//MoveEvent event = {.x =5, .y = 4};
}
Run Code Online (Sandbox Code Playgroud)
我认为这可能是与CTRP,但改变Event<MoveEvent>来Event<int>产生同样的问题.此外,我认为这是与POD的问题,而是std::is_pod返回true了MoveEvent.那么这里的问题是什么?为什么我不能使用struct初始化?
我很好奇,如果现代的c ++标准人们已经考虑或添加了C#的“对象初始化器”语法。例如,在C#中,我可以在初始化期间像这样初始化一个对象的成员:
StudentName student2 = new StudentName
{
FirstName = "Craig",
LastName = "Playstead"
};
public class StudentName {
public string FirstName;
public string LastName;
};
Run Code Online (Sandbox Code Playgroud)
如果人们计划将标准的“对象初始值设定项”语法添加到现代C ++中,它将非常方便。C ++ 11,C ++ 14,C ++ 17,C ++ 20等
它当前是否存在于现代C ++规范中?